> Что делает dispatch_sync в GCD? (iOS, Swift)
Уровень: senior · Роль: mobile · Категория: Технические вопросы
Компании: Московская биржа, VK, Яндекс
Стек: iOS, Swift
> Пример ответа
Короткий ответ
dispatch_sync - это функция Grand Central Dispatch, которая синхронно отправляет блок или замыкание в указанную очередь и блокирует текущий поток до завершения его выполнения. В отличие от dispatch_async, она не возвращает управление, пока задача не будет полностью выполнена. Используется для синхронизации доступа к общим ресурсам или для ожидания результата работы другой очереди, но требует осторожности из-за риска deadlock при вызове на главной очереди или из той же очереди.
Подробное объяснение
dispatch_sync - часть C-интерфейса GCD, в Swift доступна как DispatchQueue.sync. Основное поведение:
- блокирует вызывающий поток до завершения переданного замыкания;
- замыкание выполняется на целевой очереди, но вызывающий поток ждёт;
- если очередь серийная и текущий поток уже выполняет задачу на ней - возникает deadlock, так как очередь не может запустить новую задачу, пока текущая не завершится, а текущая ждёт завершения новой.
Ключевые сценарии использования:
- синхронное обновление UI из фоновой очереди - отправка блока на main queue;
- защита общего ресурса через серийную очередь вместо lock;
- ожидание завершения группы задач перед продолжением.
Важные нюансы:
- на concurrent queue
dispatch_syncне создаёт deadlock, если вызывается не из той же очереди, но всё равно блокирует поток; - вызов
syncна главной очереди из главного потока - гарантированный deadlock; syncна серийной очереди из той же очереди - deadlock;- для обратной совместимости с ObjC-кодом используется
dispatch_sync, в Swift - методsyncнаDispatchQueue.
На практике
В реальном коде dispatch_sync встречается реже, чем async, потому что блокировка потока - дорогая операция и источник ошибок. Основные практические применения:
- обновление UI:
DispatchQueue.main.syncиз фонового потока, когда нужно гарантировать, что UI обновлён до продолжения работы (например, при snapshot); - синхронизация доступа к mutable state через серийную очередь - альтернатива
NSLockили@synchronized; - ожидание завершения операции в тестах или при инициализации.
Частая замена - async + DispatchGroup или semaphore, если нужно дождаться результата, не блокируя поток. На практике для синхронизации данных чаще используют DispatchQueue.async с барьером (barrier), а sync - только для коротких критических секций.
Пример кода
SWIFT// Серийная очередь для защиты ресурсаprivate let queue = DispatchQueue(label: "com.example.sync")private var _value: Int = 0var value: Int {get { queue.sync { _value } }set { queue.sync { _value = newValue } }}// Синхронное обновление UI из фоновой очередиDispatchQueue.global().async {let result = heavyComputation()DispatchQueue.main.sync {self.label.text = result}}// Опасный пример - deadlockDispatchQueue.main.sync { // вызывается из main thread// никогда не выполнится}
Как отвечать на собеседовании
Начни с точного определения: синхронная отправка, блокировка вызывающего потока. Затем приведи пример использования и обязательно упомяни deadlock - это ключевой момент, который проверяет понимание. Расскажи про разницу между серийной и concurrent очередью в контексте sync. Если спросят про альтернативы - назови async + DispatchGroup, semaphore, barrier. Покажи, что понимаешь, когда sync оправдан, а когда лучше избегать. Хорошо добавить сравнение с async по стоимости и поведению.
Что проверяет интервьюер
- понимание модели выполнения GCD: очереди, потоки, блокировка;
- знание последствий блокировки потока и риска deadlock;
- умение выбрать правильный инструмент для синхронизации;
- знание Swift API (
DispatchQueue.sync) и C-функцииdispatch_sync; - способность объяснить разницу между sync и async на конкретных примерах.
Типичные ошибки
- утверждение, что
syncвыполняется в текущем потоке - это неверно, он выполняется на целевой очереди, но блокирует текущий; - игнорирование deadlock при вызове на main queue из main thread;
- использование
syncдля длительных операций - блокирует поток без необходимости; - путаница между
syncиasyncпри работе с concurrent queue; - забывание, что
syncна серийной очереди из той же очереди - deadlock, даже если очередь не main.
> Похожие задачи по mobile
В чем разница UIView и UIViewController в iOS и зачем нужен UIViewController
Какие существуют модификаторы доступа в Swift
Что такое сильные и слабые ссылки в iOS?
Какие преимущества дает использование value types в Swift
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью