Ответ
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()