Чем OperationQueue отличается от DispatchQueue и когда его использовать?

«Чем OperationQueue отличается от DispatchQueue и когда его использовать?» — вопрос из категории Многопоточность, который задают на 23% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

OperationQueue — это высокоуровневая абстракция над очередями GCD, построенная на объектах Operation. Он предоставляет более сложные модели управления задачами, чем DispatchQueue.

Ключевые отличия и возможности OperationQueue:

Особенность OperationQueue DispatchQueue (GCD)
Абстракция Высокоуровневая (объекты Operation) Низкоуровневая (блоки/замыкания)
Зависимости ✅ Да. operationB.addDependency(operationA) ❌ Нет (реализуется вручную)
Приоритет операции queuePriority (.veryLow ... .veryHigh) Приоритет очереди (QoS)
Ограничение параллелизма ✅ Да. maxConcurrentOperationCount Только через семафоры
Отмена ✅ Да. operation.cancel() / queue.cancelAllOperations() Только для DispatchWorkItem
Приостановка очереди queue.isSuspended = true ❌ Нет
Переиспользование задач ✅ Да. Operation — это переиспользуемый класс ❌ Замыкание выполняется один раз

Типичные сценарии использования OperationQueue:

  1. Задачи с зависимостями: Загрузка данных -> их обработка -> обновление UI.
  2. Управление параллелизмом: Ограничение числа одновременных сетевых запросов.
  3. Сложная отмена: Остановка цепочки связанных операций.

Пример (загрузка и обработка изображения):

let processingQueue = OperationQueue()
processingQueue.maxConcurrentOperationCount = 2

let downloadOp = BlockOperation {
    print("1. Загрузка данных с сервера")
}

let processOp = BlockOperation {
    print("2. Обработка данных")
}

let updateUIOp = BlockOperation {
    print("3. Обновление интерфейса")
}

// Устанавливаем зависимости
processOp.addDependency(downloadOp)
updateUIOp.addDependency(processOp)

// Все операции выполнятся в правильном порядке
processingQueue.addOperations([downloadOp, processOp, updateUIOp], waitUntilFinished: false)

Вывод: Используйте DispatchQueue для простых фоновых задач. Выбирайте OperationQueue, когда нужны зависимости, тонкий контроль над параллелизмом или возможность отмены группы операций.