Ответ
Operation — это абстрактный класс в Foundation, представляющий инкапсулированную задачу. Он используется вместе с OperationQueue для высокоуровневого управления многопоточностью, поддерживая зависимости, отмену и контроль состояния.
Основные возможности:
- Зависимости: Операция B может начаться только после завершения операции A (
opB.addDependency(opA)). - Отмена: Поддержка кооперативной отмены через флаг
isCancelled. - Состояния:
isReady,isExecuting,isFinished,isCancelled(KVO-совместимые). - Приоритет: Установка
qualityOfService(.userInteractive,.utilityи т.д.). - Блоки операций: Использование
BlockOperationдля быстрого создания задач.
Пример создания кастомной операции:
class DataProcessingOperation: Operation {
let inputData: String
var outputData: String?
init(data: String) {
self.inputData = data
}
override func main() {
// 1. Всегда проверяем отмену в начале и во время длительной работы
guard !isCancelled else { return }
// 2. Выполняем полезную работу
print("Обработка данных: (inputData)")
// Имитация работы
Thread.sleep(forTimeInterval: 1.0)
guard !isCancelled else { return } // Проверка в процессе
outputData = inputData.uppercased()
print("Операция завершена")
}
}
// Использование с очередью
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 2 // Ограничиваем параллелизм
let op1 = DataProcessingOperation(data: "hello")
let op2 = DataProcessingOperation(data: "world")
// Настраиваем зависимость: op2 начнется только после op1
op2.addDependency(op1)
queue.addOperations([op1, op2], waitUntilFinished: false)
// Отмена всех операций в очереди
// queue.cancelAllOperations()
Operation vs GCD (Grand Central Dispatch):
| Особенность | Operation / OperationQueue | GCD (DispatchQueue) |
|---|---|---|
| Уровень абстракции | Высокий (объектно-ориентированный) | Низкий (C-API, блоки/замыкания) |
| Зависимости | Есть (встроенная поддержка) | Нет (реализуется вручную) |
| Отмена | Есть (кооперативная) | Нет (для выполняющейся задачи) |
| Состояние операции | Есть (KVO) | Нет |
| Производительность | Небольшой оверхед | Минимальный оверхед |
Вывод: Используйте OperationQueue для сложных задач с зависимостями и необходимостью отмены. Для простых фоновых задач часто достаточно DispatchQueue.