← Назад к вопросам

Какие высокоуровневые операции поддерживает OperationQueue?

2.0 Middle🔥 161 комментариев
#Многопоточность и асинхронность

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Высокоуровневые операции в OperationQueue

OperationQueue в iOS/macOS — это мощная абстракция для управления очередями задач, построенная поверх Grand Central Dispatch (GCD). Она предоставляет ряд высокоуровневых возможностей, которые выходят за рамки простого выполнения блоков кода. Вот ключевые поддерживаемые операции:

1. Управление зависимостями (Dependencies)

Позволяет определять порядок выполнения операций: операция B начнется только после завершения операции A.

let downloadOp = BlockOperation { print("Downloading data...") }
let parseOp = BlockOperation { print("Parsing data...") }
let saveOp = BlockOperation { print("Saving data...") }

parseOp.addDependency(downloadOp)
saveOp.addDependency(parseOp)

let queue = OperationQueue()
queue.addOperations([downloadOp, parseOp, saveOp], waitUntilFinished: false)

2. Приоритеты выполнения (QueuePriority и qualityOfService)

  • queuePriority: .veryLow, .low, .normal, .high, .veryHigh
  • qualityOfService: .userInteractive, .userInitiated, .utility, .background
let criticalOp = BlockOperation { /* Critical task */ }
criticalOp.queuePriority = .veryHigh
criticalOp.qualityOfService = .userInteractive

3. Отмена операций (Cancellation)

Поддержка кооперативной отмены через проверку флага isCancelled.

class DataProcessingOperation: Operation {
    override func main() {
        guard !isCancelled else { return }
        // Выполнение работы
        
        for item in items {
            if isCancelled { break }
            // Обработка элемента
        }
    }
}

let operation = DataProcessingOperation()
queue.addOperation(operation)
operation.cancel() // Устанавливает флаг isCancelled

4. Наблюдение за состоянием (KVO-совместимые свойства)

  • isReady, isExecuting, isFinished, isCancelled
  • Можно использовать KVO для отслеживания изменений состояния

5. Ограничение параллелизма (maxConcurrentOperationCount)

Контроль количества одновременно выполняемых операций.

let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1 // Серийная очередь
queue.maxConcurrentOperationCount = 3 // Не более 3 параллельных задач
queue.maxConcurrentOperationCount = .max // Система определяет оптимальное количество

6. Приостановка очереди (isSuspended)

Временная приостановка выполнения новых операций без отмены текущих.

queue.isSuspended = true // Новые операции не начнут выполняться
queue.isSuspended = false // Возобновление выполнения

7. Группировка операций (addOperations:waitUntilFinished)

Добавление массива операций с возможностью синхронного ожидания.

8. Блоки завершения (completionBlock)

Выполнение блока кода после завершения операции независимо от результата.

let operation = BlockOperation { /* Основная работа */ }
operation.completionBlock = {
    print("Operation completed. Thread: \(Thread.current)")
}

9. Кастомные операции (Subclassing Operation)

Создание собственных классов операций с полным контролем над выполнением.

class AsyncNetworkOperation: Operation {
    private var _executing = false
    private var _finished = false
    
    override var isExecuting: Bool { _executing }
    override var isFinished: Bool { _finished }
    
    override func start() {
        guard !isCancelled else { return }
        
        willChangeValue(forKey: "isExecuting")
        _executing = true
        didChangeValue(forKey: "isExecuting")
        
        // Асинхронная задача
        URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in
            self?.finish()
        }.resume()
    }
    
    private func finish() {
        willChangeValue(forKey: "isExecuting")
        willChangeValue(forKey: "isFinished")
        _executing = false
        _finished = true
        didChangeValue(forKey: "isExecuting")
        didChangeValue(forKey: "isFinished")
    }
}

10. Управление очередями (underlyingQueue)

Назначение собственной DispatchQueue для выполнения операций.

let customQueue = DispatchQueue(label: "com.example.queue", 
                                qos: .userInitiated)
let operationQueue = OperationQueue()
operationQueue.underlyingQueue = customQueue

Преимущества перед GCD:

  • Более высокий уровень абстракции — Operation инкапсулирует задачу и ее состояние
  • Встроенная поддержка отмены — в отличие от DispatchWorkItem, где отмена возможна только до начала выполнения
  • Зависимости между задачами — реализация в GCD требует дополнительного кода
  • Наблюдение за состоянием через KVO
  • Контроль параллелизма на уровне очереди и отдельных операций

Практическое применение:

  • Загрузка и обработка изображений с зависимостями
  • Последовательные сетевые запросы, где следующий зависит от результата предыдущего
  • Сложные задачи с возможностью отмены
  • Фоновые операции с разными приоритетами

OperationQueue особенно полезен в сценариях, где требуется сложная логика выполнения задач, контроль зависимостей и возможность отмены операций. Для простых асинхронных задач достаточно GCD, но для сложных рабочих процессов OperationQueue предоставляет более выразительный и управляемый API.

Какие высокоуровневые операции поддерживает OperationQueue? | PrepBro