Ответ
Нет, не всегда. Deadlock гарантированно произойдет только если sync вызывается на DispatchQueue.main из того же самого MainThread.
Механизм deadlock:
syncблокирует текущий поток до завершения переданного блока.- Если этот вызов делается из MainThread, поток блокируется и ждет.
- Поскольку
MainQueueпоследовательная, она не может начать выполнение нового блока (того, который мы передали вsync), пока не завершит текущий (тот, из которого был вызванsync). Возникает взаимная блокировка.
Пример deadlock:
// ВЫЗОВ ИЗ MAIN THREAD -> DEADLOCK
DispatchQueue.main.sync {
// Этот блок никогда не начнет выполняться
print("This will never print")
}
Безопасный вызов: Если sync на DispatchQueue.main вызывается из другого потока (например, из background очереди), deadlock не произойдет. Background поток заблокируется, main поток выполнит блок и разблокирует background поток.
Пример безопасного вызова:
DispatchQueue.global().async {
// Вызов из фонового потока — БЕЗОПАСНО
DispatchQueue.main.sync {
// Обновляем UI на MainThread
self.label.text = "Updated safely"
}
// Код продолжит выполнение здесь после завершения блока выше
}
Правило: Никогда не вызывайте DispatchQueue.main.sync из кода, который может выполняться на MainThread.