Ответ
Вызов sync на serial (последовательной) очереди может привести к взаимной блокировке (deadlock), если этот вызов выполняется из той же самой очереди.
Причина deadlock:
- Метод
syncблокирует текущий поток до полного выполнения переданного блока кода. - Serial очередь выполняет задачи строго по одной.
- Если очередь уже выполняет какую-то внешнюю задачу (например, из предыдущего
async), она не может начать новую задачу (блок изsync), так как занята. - Внешняя задача, в свою очередь, ждет завершения
sync, создавая циклическую зависимость.
Пример deadlock:
let serialQueue = DispatchQueue(label: "com.example.serial")
serialQueue.async { // Задача A начинает выполняться на очереди
// Пока выполняется эта задача A, мы пытаемся отправить sync...
serialQueue.sync { // Задача B: DEADLOCK! Очередь не может начать B, пока не завершит A.
print("Этот код никогда не выполнится")
}
}
Как избежать:
- Не вызывайте
DispatchQueue.syncиз той же serial очереди, на которую вы его отправляете. - Используйте
asyncдля фоновых задач или отправляйтеsyncна другую очередь. - Для concurrent (параллельных) очередей такой проблемы нет.