Как выполнить диспетчеризацию в основной очереди синхронно без взаимоблокировки?

Мне нужно отправить блок в основную очередь, синхронно. Я не знаю, работаю ли я сейчас в основном потоке или нет. Наивное решение выглядит следующим образом:

dispatch_sync(dispatch_get_main_queue(), block);

Но если я в данный момент нахожусь внутри блока, работающего в основной очереди, этот вызов создает взаимоблокировку. (Синхронная диспетчеризация ожидает завершения блока, но блок даже не начинает выполняться, так как мы ждем завершения текущего.)

Следующим очевидным шагом будет проверка текущей очереди.:

if (dispatch_get_current_queue() == dispatch_get_main_queue()) {
    block();
} else {
    dispatch_sync(dispatch_get_main_queue(), block);
}

Это работает, но некрасиво. Прежде чем я по крайней мере спрячу это за какой-нибудь пользовательской функцией, нет ли лучшего решения этой проблемы? Я подчеркиваю, что не могу позволить себе асинхронную отправку блока — приложение находится в ситуации, когда асинхронно отправленный блок будет выполнен «слишком поздно».

62
задан zoul 26 April 2012 в 09:28
поделиться