Ответ
GCD и Operation — это API для многопоточности в iOS/macOS, но разного уровня абстракции.
| Характеристика | GCD (Grand Central Dispatch) | Operation / OperationQueue |
|---|---|---|
| Уровень | Низкоуровневый C-API (через libdispatch). |
Высокоуровневая объектно-ориентированная абстракция над GCD. |
| Единица работы | Замыкание (closure/block), отправляемое в очередь (DispatchQueue). |
Объект (Operation — абстрактный класс, BlockOperation — конкретный). |
| Состояние | Нет явного состояния задачи. | Есть свойства (isReady, isExecuting, isFinished, isCancelled). KVO-совместимо. |
| Зависимости | Нет встроенной поддержки. Реализуется вручную (через барьеры, семафоры, группы). | Есть встроенная поддержка. operationB.addDependency(operationA). |
| Отмена | Нет встроенной отмены отправленной задачи. | Есть встроенная отмена. operation.cancel() (кооперативная). |
| Приоритет | Качество обслуживания (qos: .userInteractive, .background и т.д.). |
queuePriority (в очереди) и qualityOfService. |
| Контроль | Ограниченный. Отправил задачу — управление передано системе. | Полный. Можно переиспользовать, наблюдать за состоянием, паузировать очередь. |
Пример GCD:
// Простая фоновая задача с обновлением UI
DispatchQueue.global(qos: .userInitiated).async {
let image = self.loadImageFromNetwork() // Тяжелая работа
DispatchQueue.main.async {
self.imageView.image = image // Обновление UI в главном потоке
}
}
Пример Operation:
// Создание зависимых операций с отменой
let downloadOp = BlockOperation {
// Загрузка данных
}
let processOp = BlockOperation {
// Обработка данных
}
let updateUIOp = BlockOperation {
DispatchQueue.main.async { /* Обновить UI */ }
}
// Настройка зависимостей: обработка -> после загрузки, UI -> после обработки
processOp.addDependency(downloadOp)
updateUIOp.addDependency(processOp)
// Добавление в очередь (запуск)
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1 // Серийная очередь для примера
queue.addOperations([downloadOp, processOp, updateUIOp], waitUntilFinished: false)
// Возможность отменить все
queue.cancelAllOperations()
Когда что использовать:
- GCD: Для простых, разовых, независимых задач, где важна минимальная производительность (например, асинхронный вызов с возвратом на главный поток).
- Operation: Для сложных, связанных задач, требующих управления зависимостями, отмены, повторного использования или наблюдения за состоянием (например, цепочка загрузки и обработки данных).