← Назад к вопросам

В каком потоке выполняется код, переданный в 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.