关于冻结提示的问题的第二部分:
dispatch_sync
在队列上调用时,请始终验证此队列不是当前队列( dispatch_get_current_queue()
)。因为dispatch_sync
会将您的块放在作为第一个参数传递的队列中,然后将等待该块执行后再继续。
因此,如果dispatch_get_current_queue()
您将块入队的队列相同,即在您的情况下是主队列,则主队列将阻塞对 dispatch_sync 的调用,直到......主队列执行了该块,但它不能,由于队列被阻塞,你在这里有一个漂亮的死锁。
一种解决方案([编辑] 直到 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]
按照@meaning-matters 的建议进行测试。
顺便说一句,你确定你需要dispatch_sync
吗?我想稍后发送你的通知,避免阻塞直到它被发送,在你的情况下是可以接受的,所以你也可以考虑使用dispatch_async
(而不是使用dispatch_sync
和需要队列比较条件),这也可以避免死锁问题。