В чем разница между главной (main) и глобальной (global) очередью в GCD?

Ответ

Главная очередь (DispatchQueue.main) — это последовательная (serial) очередь, привязанная к главному потоку приложения. Используется исключительно для операций с пользовательским интерфейсом.

Глобальные очереди (DispatchQueue.global()) — это набор параллельных (concurrent) очередей общего назначения с разными уровнями приоритета (Quality of Service, QoS). Используются для выполнения фоновых задач.

Сравнение: Характеристика Главная очередь (DispatchQueue.main) Глобальные очереди (DispatchQueue.global(qos:))
Тип Serial (последовательная) Concurrent (параллельная)
Назначение Обновление UI Фоновые задачи (сеть, вычисления, I/O)
Поток Главный поток Фоновые потоки из пула
Приоритет (QoS) .userInteractive (фактически) .userInitiated, .utility, .background и др.
Доступ Системный синглтон Системные синглтоны для каждого QoS

Правило: Все операции, изменяющие UI, должны выполняться на главной очереди.

Пример типичного паттерна:

// 1. Запускаем тяжелую задачу в фоне (глобальная очередь)
DispatchQueue.global(qos: .userInitiated).async {
    let processedImage = self.applyFilter(to: image)

    // 2. Возвращаем результат на главную очередь для обновления UI
    DispatchQueue.main.async {
        self.imageView.image = processedImage
    }
}

Уровни QoS глобальных очередей (от высокого к низкому):

  • .userInteractive — для анимаций или мгновенного отклика.
  • .userInitiated — для действий, инициированных пользователем, требующих быстрого результата.
  • .default — средний приоритет.
  • .utility — долгие задачи с индикатором прогресса (например, импорт данных).
  • .background — задачи, невидимые для пользователя (например, предварительная загрузка).

Ответ 18+ 🔞

А, ну это же классика, блядь! Сейчас объясню, как устроена эта кухня, чтобы ты не наебался с интерфейсом.

Смотри, есть у нас Главная очередь (DispatchQueue.main). Это, сука, царица бала, единственная и неповторимая. Она последовательная, то есть задачи там идут одна за другой, как в очереди за колбасой в девяностые. И живёт она строго в главном потоке. Её священная миссия — всё, что связано с мордой приложения: тронул кнопку, обновил картинку, пошевелил анимацию. Всё на неё.

А есть Глобальные очереди (DispatchQueue.global()). Это уже, блядь, рабочие лошадки, орда параллельных чертей. Их наштамповано несколько штук с разной важностью — Quality of Service, или QoS. Хуярь сюда всё, что не касается UI: сетевые запросы, вычисления, чтение файлов — всю эту тягомотину.

Короче, смотри таблицу, чтобы не ебать мозги:

Признак Главная очередь (DispatchQueue.main) Глобальные очереди (DispatchQueue.global(qos:))
Тип Serial (одна за другой) Concurrent (все сразу, как тараканы)
Предназначение Только UI, больше ни хуя! Фоновая работа (сеть, вычисления и прочая хуйня)
Поток Главный поток, один-единственный Фоновые потоки, их там овердохуища
Важность (QoS) По факту .userInteractive Есть выбор: .userInitiated, .utility, .background и другие
Как достать Готовая системная штука Такие же готовые системные штуки, но на каждый случай жизни

Железное правило, ёпта: Всё, что трогает интерфейс, должно делаться на главной очереди. Иначе получишь краш, кривой интерфейс и волнение ебать на ровном месте.

Как этим пользоваться, чтобы не обосраться? Да вот так, классический манёвр:

// 1. Пихаем тяжёлую хуйню в фон (на глобальную очередь)
DispatchQueue.global(qos: .userInitiated).async {
    let processedImage = self.applyFilter(to: image) // Долгая обработка

    // 2. Как только всё сделали — СРОЧНО возвращаем результат на главную, чтобы обновить картинку!
    DispatchQueue.main.async {
        self.imageView.image = processedImage // Вот тут уже трогаем UI
    }
}

А эти самые уровни важности (QoS) для глобальных очередей, от самого срочного до "да похуй":

  • .userInteractive — для анимаций или когда нужен мгновенный отклик, прям щас.
  • .userInitiated — пользователь что-то нажал и ждёт быстрого результата (например, открыть документ).
  • .default — среднячок, если не знаешь, что выбрать.
  • .utility — долгие процессы, где можно показывать прогресс-бар (типа импорта данных).
  • .background — задачи, о которых пользователь даже не должен догадываться (например, синхронизация или предзагрузка). Поставил и забыл, в рот меня чих-пых.

Вот и вся магия. Главное — не путай где что, и будет тебе счастье.