Ответ
Вызов 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.