Ответ
DispatchQueue (GCD) и OperationQueue — инструменты для многопоточности, но разного уровня абстракции и возможностей.
DispatchQueue (Grand Central Dispatch)
- Уровень: Низкоуровневый C API.
- Модель: Очереди (serial/concurrent) + блоки кода (closures).
- Ключевые особенности:
- Простота и эффективность для разовых задач.
- Управление через Quality of Service (QoS):
.userInteractive,.backgroundи т.д. - Нет встроенной поддержки зависимостей между задачами.
- Сложность отмены запущенной задачи.
Пример: Простая фоновая задача.
let backgroundQueue = DispatchQueue(label: "com.app.background", qos: .background)
backgroundQueue.async {
let processedData = heavyCalculation()
DispatchQueue.main.async {
updateUI(with: processedData)
}
}
OperationQueue
- Уровень: Высокоуровневая абстракция на основе
Operation(объектно-ориентированная). - Модель: Очередь операций (
Operationподклассы илиBlockOperation). - Ключевые особенности:
- Зависимости: Операции могут ждать завершения других (
addDependency). - Отмена: Легко отменить всю очередь или конкретную операцию (
cancel()). - Контроль параллелизма:
maxConcurrentOperationCount. - Наблюдение: KVO для свойств
isFinished,isCancelled. - Переиспользование: Можно создавать библиотеки операций.
- Зависимости: Операции могут ждать завершения других (
Пример: Задачи с зависимостями.
let downloadQueue = OperationQueue()
downloadQueue.maxConcurrentOperationCount = 2
let downloadOp = BlockOperation { downloadFile() }
let parseOp = BlockOperation { parseFile() }
let updateUIOp = BlockOperation { DispatchQueue.main.async { updateUI() } }
// Установка зависимостей: парсинг ждет загрузки, UI ждет парсинга.
parseOp.addDependency(downloadOp)
updateUIOp.addDependency(parseOp)
// Добавление на очередь
downloadQueue.addOperations([downloadOp, parseOp], waitUntilFinished: false)
OperationQueue.main.addOperation(updateUIOp)
Сводная таблица выбора
| Критерий | Выберите DispatchQueue |
Выберите OperationQueue |
|---|---|---|
| Зависимости задач | Нет | Да (ключевое преимущество) |
| Приоритет отмены | Низкий | Высокий (легко отменить) |
| Тип задачи | Простая, разовая | Сложная, составная, переиспользуемая |
| Контроль параллелизма | Только через типы очередей | Точный контроль (maxConcurrentOperationCount) |
| Состояние задачи | Не отслеживается | Отслеживается (KVO) |
Практическое правило: Начинайте с DispatchQueue для простых асинхронных задач. Переходите на OperationQueue, когда появляются зависимости между задачами, требование их отмены или необходимость сложного управления очередью.