Ответ
Основной риск — взаимная блокировка (deadlock), если вызвать sync на текущей последовательной (serial) очереди. Это происходит потому, что sync блокирует текущий поток до завершения переданного блока, который никогда не начнет выполняться, если очередь занята ожиданием.
Классический опасный пример на главном потоке:
// Вызов из main thread приведет к deadlock
DispatchQueue.main.sync {
print("Этот код никогда не выполнится.")
}
Почему это происходит: DispatchQueue.main — последовательная очередь. Вызов sync из main thread блокирует его, ожидая выполнения блока. Но этот блок может начать выполняться только тогда, когда main thread освободится, что создает циклическую зависимость.
Best practices:
- Избегайте
syncна main queue из main thread. - Проверяйте текущую очередь перед вызовом
sync. - Предпочитайте
asyncдля всех операций, не требующих немедленного синхронного результата, особенно в UI-коде. - Для безопасного выполнения кода на текущей очереди используйте проверку:
if DispatchQueue.isCurrentQueueSerial { // Выполняем блок напрямую или используем async block() } else { queue.sync { block() } }Используйте
syncосознанно, только когда необходимо дождаться результата, и вы уверены в отсутствии конфликта очередей.