Какие альтернативы NSOperation существуют для отслеживания выполнения задач в iOS
Что проверяют
Знаете ли вы современный набор инструментов конкурентности и умеете ли не просто запустить задачу, а следить за прогрессом, отменой и завершением группы задач. Следом спрашивают, как переписать цепочку операций с зависимостями на Swift Concurrency.
Как отвечать
Сначала назовите, что даёт Operation: зависимости через addDependency, отмену, состояния isExecuting и isFinished с KVO, maxConcurrentOperationCount, общий прогресс очереди через progress. Альтернативы сравнивайте по этим же пунктам:
- Swift Concurrency:
async/await,Taskсcancel()и проверкойTask.isCancelledилиtry Task.checkCancellation(),withTaskGroupдля набора параллельных задач с результатами по мере готовности. Отмена распространяется на дочерние задачи. Основной выбор для нового кода; AsyncStream: канал промежуточных событий, например процентов загрузки, который вызывающий читает черезfor await;- GCD:
DispatchGroupсnotify(queue:)для момента, когда все задачи закончились, иDispatchWorkItemсcancel(), который отменяет только ещё не начатую работу; Progressиз Foundation: иерархический прогресс сtotalUnitCountиcompletedUnitCount, отменой и дочерними прогрессами. Наблюдается через KVO и легко выводится в интерфейс;- Combine: поток событий и статусов через
Publisher. В существующих проектах живёт, в новом коде его всё чаще заменяют асинхронными последовательностями; URLSession: у сетевой задачи свойprogressи делегаты, а для загрузок в фоне нужнаbackground-конфигурация;BGTaskScheduler: если работа должна выполняться, когда приложение свёрнуто.
Где спотыкаются
Называют OperationQueue альтернативой NSOperation. Это одна связка: очередь исполняет операции.
Думают, что cancel() у Task останавливает код. Отмена кооперативная: пока задача сама не проверила флаг или не дошла до отменяемой точки ожидания, она работает дальше.
Используют DispatchGroup с enter() и leave() и забывают leave() в ветке ошибки. Тогда notify не сработает никогда, а баг проявится только в редком сценарии, который в тестах не воспроизвели.