Как работает метод cancel() у NSOperation?

«Как работает метод cancel() у NSOperation?» — вопрос из категории Многопоточность, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Метод cancel() не прерывает выполнение операции напрямую. Он выполняет кооперативную отмену, устанавливая свойство isCancelled в true и отправляя KVO-уведомления.

Как это работает:

  1. Вызов cancel() меняет только внутреннее состояние операции.
  2. Сама операция должна периодически проверять isCancelled и корректно завершать свою работу.
  3. Операция остается в очереди (OperationQueue) до тех пор, пока не перейдет в состояние isFinished = true.

Пример реализации в кастомной Operation:

class LongRunningOperation: Operation {
    override func main() {
        // 1. Проверка на отмену перед началом работы
        guard !isCancelled else { return }

        // 2. Длительная задача с периодическими проверками
        for item in largeArray {
            // Критически важная проверка в цикле
            if isCancelled { 
                // Очистка ресурсов, если необходимо
                return 
            }
            process(item)
        }
    }
}

Важные нюансы:

  • Асинхронные операции: Отмена сложнее, необходимо также отменять все внутренние асинхронные задачи (например, URLSessionDataTask).
  • Состояния KVO: Флаги isExecuting и isFinished должны меняться разработчиком с отправкой корректных KVO-уведомлений.
  • Немедленный выход: После проверки isCancelled операция должна как можно быстрее завершить main() и перейти в состояние isFinished.