Очереди задач в Swift: GCD, OperationQueue и Swift Concurrency

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Очереди задач в Swift: от GCD до Swift Concurrency

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

1. Grand Central Dispatch (GCD) — основа параллелизма

GCD — это низкоуровневая библиотека C, интегрированная в Swift. Она управляет пулом потоков и предоставляет два типа очередей:

  • Serial (последовательные) — задачи выполняются одна за другой в порядке добавления.
  • Concurrent (параллельные) — задачи запускаются одновременно, порядок завершения не гарантирован.

Пример создания и использования очереди:

import Foundation

// Создаём последовательную очередь
let serialQueue = DispatchQueue(label: "com.example.serial")

serialQueue.async {
    print("Задача 1 началась")
    sleep(1)
    print("Задача 1 завершена")
}

serialQueue.async {
    print("Задача 2 началась")
    sleep(1)
    print("Задача 2 завершена")
}

// Параллельная очередь
let concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)

concurrentQueue.async {
    print("Параллельная задача A")
}

concurrentQueue.async {
    print("Параллельная задача B")
}

Ключевые возможности GCD:

  • DispatchQueue.main — главная очередь (UI-поток).
  • DispatchQueue.global(qos: .userInitiated) — глобальные очереди с приоритетом (QoS).
  • dispatchGroup — синхронизация нескольких задач.
  • dispatchSemaphore — контроль доступа к ресурсам.

2. OperationQueue — объектно-ориентированная абстракция

OperationQueue построена поверх GCD, но предоставляет более высокоуровневый API. Основные преимущества:

  • Управление зависимостями между операциями.
  • Отмена задач (cancel).
  • Мониторинг состояния (isFinished, isExecuting).
  • Максимальное количество параллельных операций.

Пример с использованием BlockOperation:

import Foundation

let operationQueue = OperationQueue()
operationQueue.maxConcurrentOperationCount = 2

let operation1 = BlockOperation {
    print("Операция 1: загрузка данных")
    sleep(2)
    print("Операция 1 завершена")
}

let operation2 = BlockOperation {
    print("Операция 2: обработка")
    sleep(1)
    print("Операция 2 завершена")
}

// Устанавливаем зависимость: операция 2 начнётся только после завершения операции 1
operation2.addDependency(operation1)

operationQueue.addOperations([operation1, operation2], waitUntilFinished: false)

// Отмена операции
operation1.cancel()

Когда использовать OperationQueue:

  • Сложные цепочки задач с зависимостями.
  • Необходимость тонкого контроля (пауза, отмена).
  • Работа с KVO (Key-Value Observing) для мониторинга.

3. Swift Concurrency — современный подход (iOS 13+, macOS 10.15+)

Начиная с Swift 5.5, Apple представила встроенную поддержку асинхронного программирования через async/await, Task и TaskGroup. Это более безопасный и читаемый способ работы с параллелизмом.

Базовый пример:

import Foundation

func fetchUserData() async -> String {
    // Имитация сетевого запроса
    try? await Task.sleep(nanoseconds: 2 * 1_000_000_000)
    return "User data loaded"
}

func processData() async {
    let data = await fetchUserData()
    print("Получено: \(data)")
}

// Запуск асинхронной задачи
Task {
    await processData()
}

// Параллельное выполнение с TaskGroup
await withTaskGroup(of: String.self) { group in
    for i in 1...3 {
        group.addTask {
            let result = await fetchUserData()
            return "Задача \(i): \(result)"
        }
    }
    
    for await result in group {
        print(result)
    }
}

Основные компоненты Swift Concurrency:

  • async — маркировка асинхронной функции.
  • await — ожидание результата асинхронной операции.
  • Task — единица асинхронной работы.
  • TaskGroup —

Рекомендаций