Какие основные инструменты предоставляет Grand Central Dispatch (GCD) в iOS?

«Какие основные инструменты предоставляет Grand Central Dispatch (GCD) в iOS?» — вопрос из категории Многопоточность, который задают на 23% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Grand Central Dispatch (GCD) — это низкоуровневый фреймворк для управления параллельными операциями через потоки (threads). Основные инструменты:

1. Очереди (DispatchQueue)

Очереди — это абстракция над потоками. Они бывают:

  • Последовательные (Serial): Задачи выполняются строго по одной.
  • Параллельные (Concurrent): Задачи могут выполняться одновременно на нескольких потоках.

Типы очередей:

// Главная очередь (последовательная, UI-поток)
DispatchQueue.main.async { /* Обновление интерфейса */ }

// Глобальные параллельные очереди с приоритетами качества обслуживания (QoS)
DispatchQueue.global(qos: .userInteractive).async { /* Критичная для UI задача */ }
DispatchQueue.global(qos: .userInitiated).async { /* Действие пользователя */ }
DispatchQueue.global(qos: .default).async { /* По умолчанию */ }
DispatchQueue.global(qos: .utility).async { /* Длительная задача */ }
DispatchQueue.global(qos: .background).async { /* Фоновая задача */ }

// Создание кастомной очереди
let serialQueue = DispatchQueue(label: "com.example.serial")
let concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)

2. Группы (DispatchGroup)

Для отслеживания завершения набора задач.

let group = DispatchGroup()

for url in urls {
    group.enter() // Вход в группу
    fetchData(from: url) { 
        group.leave() // Выход из группы
    }
}

// Уведомление, когда все задачи завершены
group.notify(queue: .main) {
    print("Все данные загружены")
}

3. Семафоры (DispatchSemaphore)

Для контроля доступа к ограниченному количеству ресурсов или синхронизации.

let semaphore = DispatchSemaphore(value: 2) // Одновременно могут работать 2 потока

queue.async {
    semaphore.wait() // Захватить семафор (уменьшить счетчик)
    // Критическая секция (макс. 2 потока одновременно)
    semaphore.signal() // Освободить семафор (увеличить счетчик)
}

4. Барьеры (DispatchWorkItemFlags.barrier)

Для эксклюзивного доступа к ресурсу в параллельной очереди.

concurrentQueue.async(flags: .barrier) {
    // Эта задача выполнится ТОЛЬКО когда все предыдущие завершатся,
    // и во время её выполнения другие задачи стоять.
    // Идеально для записи в общий ресурс.
}

5. Таймеры (DispatchSourceTimer)

Более эффективная альтернатива Timer, интегрированная с очередями.

let timer = DispatchSource.makeTimerSource(queue: .global())
timer.schedule(deadline: .now(), repeating: 1.0) // Интервал 1 секунда
timer.setEventHandler { /* Действие по таймеру */ }
timer.resume()