Grand Central Dispatch (GCD) пришёл в iOS и macOS ещё в 2009 году как низкоуровневая система для организации конкурентного, асинхронного кода (многопоточность), основанная на очередях — DispatchQueue. GCD оказался гораздо лаконичнее ручного управления потоками, обеспечивая безопасное выполнение задач, синхронизацию и удобный API.
Асинхронность и многопоточность традиционно — источник большинства проблем: гонки данных, дедлоки, живые блокировки интерфейса и сложные краши. Неправильное использование очередей или попытки обращаться к UI из не-main потока приводят к багам.
Swift позволяет легко создавать фоновую работу и безопасно возвращаться на главный поток для обновления интерфейса с помощью глобальных и пользовательских очередей. Используйте DispatchQueue для асинхронной работы и DispatchGroup, если нужно дождаться завершения набора асинхронных задач.
Пример кода:
let backgroundQueue = DispatchQueue(label: "background", qos: .background) backgroundQueue.async { // выполняется в фоновом потоке let image = downloadImage() DispatchQueue.main.async { // безопасное обновление UI imageView.image = image } }
Ключевые особенности:
Что произойдет, если вызвать sync на главной очереди из главного потока?
Произойдёт deadlock: главный поток ждёт выполнения задачи на себе же, и приложение "замрёт".
DispatchQueue.main.sync { // DEADLOCK }
Может ли DispatchQueue.serial выполнять задачи параллельно?
Нет, serial очередь всегда выполняет задачи по одной, однако если создать несколько serial-очередей, они выполняются параллельно между собой.
Разрешено ли обновлять интерфейс не из главного потока?
Нет, любые манипуляции с UIKit (или SwiftUI View rendering) можно делать только из DispatchQueue.main. Нарушение приведёт к нестабильной работе и сбоям.
В фоновом потоке загружают данные, сразу обновляют UI — приложение иногда крашится или Interface зависает. Кроме того, используют shared mutable state между потоками без синхронизации.
Плюсы:
Минусы:
Организация всех обновлений UI только на DispatchQueue.main, выделенные очереди для работы с большими данными, использование DispatchGroup для контроля завершения асинхронных задач.
Плюсы:
Минусы: