Вопрос проверяет понимание причин дедлока и методов его предотвращения при использовании GCD.
Нельзя вызывать sync на той же последовательной очереди, в которой уже находитесь. Вместо этого следует использовать async или выполнять синхронный вызов на другой очереди, чтобы избежать ситуации, когда очередь ждёт сама себя.
Причина дедлока:
Последовательная очередь ждет завершения синхронной задачи, а задача не стартует, пока текущая не завершится.
Пример дедлока:
let queue = DispatchQueue(label: "serial")
queue.sync {
// внутри той же очереди
queue.sync { print("Никогда не выполнится") }
}Способы избежать:
Использовать async для вложенных вызовов.
Для синхронных задач — всегда на разных очередях (главная vs фоновая).
Проверять DispatchQueue.getSpecific/setSpecific, чтобы определить текущую очередь.
Примеры решения:
queue.async {
queue.sync { /* безопасно, т.к. другая задача встала асинхронно */ }
}Вывод:
Понимание работы последовательных очередей и выбор между sync и async помогает избежать блокировок.