Ответ
Задачу можно отменить, вызвав метод cancel() у экземпляра NSOperation или Operation. Однако отмена является кооперативной — операция не прекращается мгновенно, а лишь устанавливает свойство isCancelled в true. Код внутри операции должен периодически проверять это свойство и корректно завершать свою работу.
Правильная реализация отмены в кастомной операции:
class MyLongOperation: Operation {
override func main() {
// 1. Проверить отмену перед началом работы
guard !isCancelled else { return }
// 2. Выполнять длительную работу с периодическими проверками
for i in 1...1000 {
if isCancelled { // 3. Проверка в цикле
// Очистка ресурсов при необходимости
return
}
// ... выполнение шага работы ...
print("Step (i)")
}
}
}
// Использование
let operationQueue = OperationQueue()
let operation = MyLongOperation()
operationQueue.addOperation(operation)
// Отмена операции через 2 секунды
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
operation.cancel() // Устанавливает isCancelled = true
}
Важные моменты:
- После вызова
cancel()операция остается в очереди до момента, когда ееmain()метод завершится. - Свойства
isFinishedиisExecutingменяются системой только после реального завершенияmain(). - Для отмены всех операций в очереди используйте
operationQueue.cancelAllOperations(). - Отмененные зависимости (
addDependency) не препятствуют запуску зависящей операции, если она готова к выполнению.