Ответ 1
Во второй части вашего вопроса относительно намека на замораживание:
При вызове dispatch_sync
в очереди всегда убедитесь, что эта очередь уже не является текущей очередью (dispatch_get_current_queue()
). Поскольку dispatch_sync
будет помещать в очередь ваш блок в очереди, переданной как первый параметр, а затем будет ждать выполнения этого блока перед продолжением.
Итак, если dispatch_get_current_queue()
и очередь, в которую вы вставляете свой блок, одинаковы, а именно главная очередь в вашем случае, основная очередь будет блокировать вызов dispatch_sync до тех пор, пока... главная очередь не будет выполнена блоком, но он не может, поскольку очередь заблокирована, , и у вас есть красивый тупик здесь.
Одно решение ([EDIT] до iOS6):
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_block_t block = ^
{
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationAuthenticationSuccess object:nil userInfo:ret];
};
if (dispatch_get_current_queue() == main)
block(); // execute the block directly, as main is already the current active queue
else
dispatch_sync(main, block); // ask the main queue, which is not the current queue, to execute the block, and wait for it to be executed before continuing
[РЕД.] Будьте осторожны, dispatch_get_current_queue()
используется только для целей отладки и никогда в производстве. Фактически, dispatch_get_current_queue
устарел с iOS6.1.3.
Если вы находитесь в конкретном случае основной очереди (которая связана только с основным потоком), вы можете вместо этого проверить [NSThread isMainThread]
, как это было предложено в @смыслах.
Кстати, вы уверены, что вам нужно dispatch_sync
в вашем случае?
Я предполагаю, что вы отправляете свое уведомление немного позже, избегая блокировки до его отправки, приемлемо в вашем случае, поэтому вы можете также рассмотреть возможность использования dispatch_async
(вместо использования dispatch_sync
и необходимости условия сравнения в очереди), что также избегайте проблем с блокировкой.