← Назад к вопросам
В каком потоке выполняется код, переданный в GCD?
2.2 Middle🔥 251 комментариев
#Многопоточность и асинхронность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
В каком потоке выполняется код в GCD
Grand Central Dispatch (GCD) — это мощная система для управления многопоточностью в iOS. Код, переданный в GCD, выполняется в разных потоках в зависимости от типа очереди и приоритета задачи.
Типы очередей и потоки выполнения
Main Queue (главный поток):
DispatchQueue.main.async {
// Код выполнится в главном потоке (UI поток)
DispatchQueue.OperationQueue.main.addOperation {
label.text = "Hello"
}
}
- Всегда выполняется в главном потоке (main thread, thread 1)
- Используется для обновления UI
- Выполняется последовательно (никогда не параллельно)
- Если вызвать из main потока — выполнится после текущей операции
Global Queue (глобальные очереди):
DispatchQueue.global().async {
// Код выполнится в одном из фоновых потоков
let data = fetchData()
DispatchQueue.main.async {
updateUI(data)
}
}
- Выполняется в фоновых потоках из глобального пула
- Полностью параллельно
- Есть разные приоритеты:
.userInteractive,.userInitiated,.default,.utility,.background - Более высокий приоритет = больше CPU ресурсов
Custom Serial Queue:
let serialQueue = DispatchQueue(label: "com.example.serial")
serialQueue.async {
// Выполнится в отдельном потоке
}
- Выполняется в отдельном фоновом потоке
- Задачи в очереди выполняются последовательно (одна за другой)
- Гарантирует порядок выполнения
- Полезна для синхронизации доступа к ресурсам
Custom Concurrent Queue:
let concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)
concurrentQueue.async {
// Может выполняться параллельно с другими задачами в этой очереди
}
- Выполняется в нескольких фоновых потоках одновременно
- Задачи могут выполняться параллельно
- Требует синхронизации при доступе к общим ресурсам
Практический пример: правильное использование GCD
class DataManager {
private let serialQueue = DispatchQueue(label: "com.example.dataQueue")
private var data: [String] = []
func addData(_ item: String) {
serialQueue.async { [weak self] in
// Безопасное добавление данных (потокобезопасно)
self?.data.append(item)
}
}
func fetchDataFromServer() {
DispatchQueue.global(qos: .userInitiated).async {
// Тяжёлая операция в фоне
let result = self.requestAPI()
DispatchQueue.main.async {
// Обновляем UI в главном потоке
self.updateUI(result)
}
}
}
}
Важные правила
✅ Обновление UI — только в DispatchQueue.main
✅ Тяжёлые операции — в DispatchQueue.global()
✅ Синхронизация доступа — используй serial queue с async
❌ Никогда не блокируй главный поток — UI зависнет
❌ Избегай глубокой вложенности — используй DispatchGroup, DispatchSemaphore
Выбор очереди зависит от задачи: используй global для IO/сети, serial для синхронизации, main только для UI.