Ответ
Вызов DispatchQueue.main.sync из того же самого (главного) потока вызывает взаимную блокировку (deadlock) из-за принципа работы синхронных операций и очередей.
Механизм deadlock:
syncблокирует текущий поток и ждет, пока переданный блок кода выполнится.- Блок кода ставится в очередь (
DispatchQueue.main) на выполнение. - Если очередь уже занята этим же потоком (главный поток выполняет наш
sync-вызов), она не может начать выполнение нового блока, пока не освободится. - Возникает циклическая зависимость: Поток ждет очередь → Очередь ждет поток.
Пример deadlock:
// Вызов из главного потока:
DispatchQueue.main.sync {
// Этот блок никогда не будет выполнен
updateUI()
}
// Поток заблокирован здесь навсегда
Решение: Всегда используйте DispatchQueue.main.async для планирования работы на главной очереди из самого главного потока.
// Правильно:
DispatchQueue.main.async {
self.updateUI()
}
Исключение: Вызов sync из другого (фонового) потока на главную очередь — безопасен и является стандартным паттерном для синхронизации результатов с UI.