Ответ
Отмена задач важна для управления ресурсами и отзывчивости UI. Механизмы различаются в зависимости от используемого API.
1. Grand Central Dispatch (GCD) - DispatchWorkItem
Задачу, представленную DispatchWorkItem, можно отменить до ее начала. Если выполнение уже началось, его нельзя прервать, но можно проверить флаг isCancelled внутри блока.
let workItem = DispatchWorkItem {
// Регулярно проверяем отмену
while !Thread.current.isCancelled {
// Долгая операция
}
}
DispatchQueue.global().async(execute: workItem)
// Отмена (остановит задачу, если она еще не началась)
workItem.cancel()
2. Operation и OperationQueue
Operation предоставляет более богатый API для отмены и зависимостей.
let operation = BlockOperation {
guard !operation.isCancelled else { return }
// Выполняем работу
}
let queue = OperationQueue()
queue.addOperation(operation)
// Отмена. Задача проверит isCancelled и завершится корректно.
operation.cancel()
3. URLSession
Любую сетевую задачу (URLSessionDataTask, URLSessionDownloadTask) можно отменить.
let task = URLSession.shared.dataTask(with: url) { data, _, _ in }
task.resume()
// Отмена. Вызовет completionHandler с ошибкой URLError.cancelled.
task.cancel()
4. Combine
Подписка возвращает AnyCancellable, вызов cancel() на котором прекращает получение значений.
var cancellables = Set<AnyCancellable>()
URLSession.shared.dataTaskPublisher(for: url)
.sink(receiveCompletion: { _ in }, receiveValue: { _ in })
.store(in: &cancellables) // Храним ссылку
// Отмена всех подписок в наборе
cancellables.forEach { $0.cancel() }
5. Swift Concurrency (async/await)
Задача, созданная с помощью Task, может быть отменена. Внутри асинхронной функции следует проверять Task.isCancelled или вызывать try Task.checkCancellation() (которая выбросит CancellationError).
let task = Task {
// Проверка 1: Выброс ошибки
try Task.checkCancellation()
// Проверка 2: Условный выход
guard !Task.isCancelled else { return }
// Долгая работа
}
// Отмена задачи
task.cancel()
Ключевой принцип: Отмена обычно кооперативна. API предоставляет флаг или уведомление, но сама задача должна регулярно проверять его и корректно завершать работу.