В каком потоке выполняется блок кода, переданный в DispatchQueue (GCD)?

Ответ

Поток выполнения определяется типом очереди (DispatchQueue), в которую отправлен блок.

Основные типы очередей:

Очередь Тип Поток выполнения Назначение
DispatchQueue.main Последовательная (serial) Главный (UI) поток Все операции с пользовательским интерфейсом.
Глобальные очереди
(DispatchQueue.global(qos:))
Параллельные (concurrent) Фоновые потоки из системного пула Параллельное выполнение нефоновых задач. QoS определяет приоритет.
Кастомные очереди
(DispatchQueue(label:))
По умолчанию последовательные, но могут быть параллельными Фоновые потоки из системного пула Организация и сериализация специфичных задач.

Примеры:

// 1. Обновление UI на главном потоке.
DispatchQueue.main.async {
    self.label.text = "Загрузка завершена"
}

// 2. Выполнение тяжелой задачи в фоне.
DispatchQueue.global(qos: .userInitiated).async {
    let processedImage = self.applyFilters(to: largeImage) // В фоновом потоке
    // Возврат результата на главный поток для отображения.
    DispatchQueue.main.async {
        self.imageView.image = processedImage
    }
}

// 3. Создание своей последовательной очереди для синхронизации.
let serialQueue = DispatchQueue(label: "com.example.serialQueue")
serialQueue.async {
    // Задачи на этой очереди выполняются по одной, в фоновых потоках.
}

Важно: GCD сам управляет созданием, переиспользованием и уничтожением потоков. Разработчик работает только с очередями.

Ответ 18+ 🔞

Давай разжую эту тему про потоки и очереди, чтобы у тебя в голове всё встало на свои места, а не болталось как хуй с винтом. Слушай сюда, но внимательно, а то потом будешь спрашивать, почему UI тормозит.

Вот смотри, есть у тебя код. Он не просто так выполняется, а в каком-то потоке. Поток — это типа рабочая лошадка, которая тащит твои инструкции. А очередь (DispatchQueue) — это, блядь, диспетчер, который решает, на какую лошадку какую телегу навесить.

Какие бывают эти самые диспетчеры-очереди:

Очередь Тип Кто работает? Зачем нужна?
DispatchQueue.main Последовательная (serial) Главный (UI) поток, он один и неповторимый Всё, что связано с интерфейсом. Только тут можно трогать кнопки, лейблы и прочую визуальную хуйню.
Глобальные очереди
(DispatchQueue.global(qos:))
Параллельные (concurrent) Фоновые потоки из общего пула, их дохуя Для любой тяжелой работы: загрузка, вычисления, обработка фото. QoS — это приоритет, говоришь системе, насколько срочно.
Свои, кастомные очереди
(DispatchQueue(label:))
По умолчанию последовательные, но можно и параллельные Тоже фоновые потоки из пула Чтобы организовать свои задачи в стройную очередь, чтобы они не лезли друг другу в жопу.

Теперь на живых примерах, чтобы понятно стало:

// 1. Тыкаем в интерфейс. ТОЛЬКО НА ГЛАВНОЙ, СУКА!
DispatchQueue.main.async {
    self.label.text = "Всё, загрузилось, можно выдыхать"
    // Если это сделать не на главной — получишь краш, и будет тебе ебаный вротберунчик.
}

// 2. Делаем что-то тяжелое, не задерживая главный поток.
DispatchQueue.global(qos: .userInitiated).async {
    // Допустим, фильтруем огромную фотку. Делаем это в фоне.
    let processedImage = self.applyFilters(to: largeImage)
    // Как закончили — ОБЯЗАТЕЛЬНО возвращаем результат на главную, чтобы показать.
    DispatchQueue.main.async {
        self.imageView.image = processedImage // Вот теперь можно.
    }
}

// 3. Создаём свою очередь, чтобы задачи шли строго по одной.
let serialQueue = DispatchQueue(label: "com.example.mySerialQueue")
serialQueue.async {
    // Задача 1
}
serialQueue.async {
    // Задача 2 начнётся ТОЛЬКО после задачи 1. Порядок, блядь!
}

Самое главное, что нужно вынести: ты, как разработчик, не паришься о создании потоков. Ты кидаешь задачи (async) в очереди, а система (GCD) сама решает, какой свободный поток из пула ей для этого использовать, создавать новый или переиспользовать старый. Твоя работа — правильно выбрать очередь.

Запомни простое правило: UI — только main, всё остальное — в global или свою очередь. Нарушишь — получишь лагующий интерфейс и пользователей, которые захотят тебя ебать в сраку. Всё гениальное просто.