Есть ли у OperationQueue API?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Да, у OperationQueue есть обширное и мощное API, которое является ключевой частью фреймворков Foundation и Concurrency в iOS/macOS разработке. OperationQueue — это высокоуровневый абстрактный слой для управления очередями задач (операций), построенный поверх Grand Central Dispatch (GCD). Его API можно разделить на несколько основных категорий.
### Основные методы управления очередью
Самое ядро API — это методы для добавления, управления и контроля выполнения операций.
let queue = OperationQueue()
// 1. Добавление операций
let operation = BlockOperation {
print("Выполняю задачу")
}
queue.addOperation(operation)
// Удобное добавление блока кода напрямую
queue.addOperation {
print("Короткая задача")
}
// 2. Добавление массива операций
let ops = [op1, op2, op3]
queue.addOperations(ops, waitUntilFinished: false) // Неблокирующий вызов
// 3. Ожидание завершения всех операций
queue.waitUntilAllOperationsAreFinished() // Блокирует текущий поток
// 4. Отмена всех операций в очереди
queue.cancelAllOperations()
### Конфигурация очереди
API предоставляет гибкие свойства для настройки поведения очереди:
// Управление параллелизмом (максимальное количество одновременных операций)
queue.maxConcurrentOperationCount = 3 // Конкретное число
queue.maxConcurrentOperationCount = .default // Системный дефолт
queue.maxConcurrentOperationCount = 1 // Последовательная очередь (альтернатива DispatchQueue.serial)
// Приоритет качества обслуживания (QoS)
queue.qualityOfService = .userInitiated
// Имя очереди (полезно для отладки)
queue.name = "com.example.imageProcessing"
// Приостановка очереди
queue.isSuspended = true // Новые операции ставятся в очередь, но не выполняются
queue.isSuspended = false // Возобновление выполнения
### Взаимодействие с текущими операциями
// Получение текущих выполняющихся операций
let currentOps = queue.operations // Массив всех операций в очереди (ожидающих и выполняющихся)
let executingOps = queue.operations.filter { $0.isExecuting }
// Получение количества операций
let operationCount = queue.operationCount // Приблизительное количество (не атомарное)
### Управление выполнением и зависимостями через Operation
Хотя это часть API Operation, OperationQueue тесно с ним интегрирован:
let downloadOp = BlockOperation { /* Загрузка */ }
let processOp = BlockOperation { /* Обработка */ }
let saveOp = BlockOperation { /* Сохранение */ }
// Установка зависимостей: processOp начнется ТОЛЬКО после downloadOp
processOp.addDependency(downloadOp)
saveOp.addDependency(processOp)
// Добавление в очередь (порядок добавления не важен благодаря зависимостям)
queue.addOperations([downloadOp, processOp, saveOp], waitUntilFinished: false)
// Приоритет внутри очереди
downloadOp.queuePriority = .high
processOp.queuePriority = .normal
// completionBlock (выполняется после завершения операции, даже если она отменена)
downloadOp.completionBlock = {
print("Загрузка завершена")
}
### Продвинутые возможности
Подклассы OperationQueue
Вы можете создавать собственные подклассы для кастомного поведения:
class CustomOperationQueue: OperationQueue {
override func addOperation(_ op: Operation) {
// Кастомная логика перед добавлением
print("Добавляю операцию: \(op.name ?? "без имени")")
super.addOperation(op)
}
}
Интеграция с DispatchQueue
OperationQueue использует GCD под капотом, но вы можете указать базовый DispatchQueue:
if #available(iOS 13.0, macOS 10.15, *) {
// Установка underlying DispatchQueue (доступно с iOS 13/tvOS 13/watchOS 6/macOS 10.15)
let dispatchQueue = DispatchQueue(label: "com.example.underlying", qos: .userInitiated)
queue.underlyingQueue = dispatchQueue
}
### Особенности и ограничения API
- Потокобезопасность: Большинство методов
OperationQueueпотокобезопасны. - Жизненный цикл: Очередь удерживает операции до их завершения.
- Отмена:
cancelAllOperations()отправляет сообщение об отмене, но операции должны поддерживать кооперативную отмену через проверкуisCancelled. - KVO-совместимость: Свойства вроде
operationCount,isSuspendedподдерживают KVO. - Главная очередь:
OperationQueue.main— специальная очередь для работы с UI.
### Практический пример использования API
class ImageProcessor {
private let processingQueue: OperationQueue = {
let queue = OperationQueue()
queue.name = "Image Processing Queue"
queue.maxConcurrentOperationCount = 4 // Оптимально для CPU-интенсивных задач
queue.qualityOfService = .userInitiated
return queue
}()
func processImages(_ images: [UIImage], completion: @escaping ([UIImage]) -> Void) {
var processedImages: [UIImage] = []
let completionOp = BlockOperation { completion(processedImages) }
for image in images {
let processOp = BlockOperation {
guard !processOp.isCancelled else { return }
let processed = self.applyFilters(to: image)
OperationQueue.main.addOperation {
processedImages.append(processed)
}
}
completionOp.addDependency(processOp)
processingQueue.addOperation(processOp)
}
// completionOp выполнится на главной очереди после всех операций
OperationQueue.main.addOperation(completionOp)
}
}
Резюме: API OperationQueue предоставляет богатый набор инструментов для управления асинхронными задачами с поддержкой зависимостей, приоритетов, отмены и приостановки. В сравнении с "чистым" GCD, он предлагает более объектно-ориентированный и удобный для сложных сценариев подход, особенно когда задачи имеют взаимозависимости или требуют более тонкого контроля над жизненным циклом.