Что произойдет, если вызвать sync на главной очереди (DispatchQueue.main)?

«Что произойдет, если вызвать sync на главной очереди (DispatchQueue.main)?» — вопрос из категории Многопоточность, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Вызов DispatchQueue.main.sync из главного потока приведет к неизбежному deadlock.

Причина: Главная очередь (main) — это serial очередь. Правило то же, что и для любой serial очереди: вызов sync из той же очереди вызывает взаимную блокировку.

  • sync блокирует текущий поток (главный) и ждет, пока блок кода выполнится на целевой очереди (main).
  • Но очередь main уже занята — она выполняет тот самый метод, из которого был вызван sync, и не может приступить к новому блоку.
  • Возникает тупик: внешний код ждет sync, а sync ждет, когда очередь освободится.

Классический пример deadlock:

// Вызов из главного потока
DispatchQueue.main.sync {
    print("Этот код никогда не выполнится")
}

Решение и best practice:

  • Всегда используйте DispatchQueue.main.async для обновления UI из фоновых потоков.
  • Никогда не используйте DispatchQueue.main.sync, если есть хотя бы малейшая вероятность, что вызов происходит из главного потока. Проверить это можно с помощью Thread.isMainThread.
  • Если необходимо выполнить код синхронно и вы не уверены в текущем потоке, безопаснее использовать async.