Ответ
OperationQueue — это высокоуровневая абстракция над GCD (Grand Central Dispatch) для управления очередями задач, представленных объектами Operation. Основные преимущества перед «чистым» GCD:
- Зависимости между операциями: Можно четко указать порядок выполнения.
- Отмена операций: Поддержка отмены как отдельных операций (
operation.cancel()), так и всей очереди. - Контроль параллелизма: Установка максимального количества одновременно выполняемых операций (
maxConcurrentOperationCount). - Состояние операции: Возможность отслеживать
isReady,isExecuting,isFinished,isCancelled. - Приоритеты: Настройка
queuePriorityиqualityOfService.
Пример: Загрузка и обработка изображения с зависимостями.
// 1. Создание кастомной операции для загрузки
class ImageLoadOperation: Operation {
let url: URL
var image: UIImage?
init(url: URL) { self.url = url }
override func main() {
guard !isCancelled else { return }
let data = try? Data(contentsOf: url) // В реальности — асинхронный запрос
image = UIImage(data: data ?? Data())
}
}
// 2. Создание операции для обработки (например, применения фильтра)
class ImageFilterOperation: Operation {
var inputImage: UIImage?
var outputImage: UIImage?
override func main() {
guard let input = inputImage, !isCancelled else { return }
// Применяем фильтр...
outputImage = applySepiaFilter(to: input)
}
}
// 3. Настройка очереди и зависимостей
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 3 // Не более 3 параллельных загрузок
let loadOp = ImageLoadOperation(url: imageURL)
let filterOp = ImageFilterOperation()
// Устанавливаем зависимость: фильтрация только после загрузки
filterOp.addDependency(loadOp)
// Передаем результат загрузки в операцию фильтрации
filterOp.completionBlock = {
filterOp.inputImage = loadOp.image
}
queue.addOperations([loadOp, filterOp], waitUntilFinished: false)
Ключевые сценарии использования:
- Последовательные цепочки задач: Например, «загрузить данные → распарсить → сохранить в кэш → обновить UI».
- Ограничение ресурсоемких операций: Например, не более 2 одновременных сетевых запросов для избежания throttling.
- Управляемая отмена: Пользователь покинул экран — отменяем все pending операции загрузки контента для этого экрана.
Недостаток: Небольшие накладные расходы по сравнению с простыми DispatchQueue.async блоками. Для тривиальных задач часто достаточно GCD.