teu*_*nks 29 multithreading cocoa-touch objective-c grand-central-dispatch
我正在使用Kiwi测试框架在我的应用程序中测试身份验证方法.在调用dispatch_sync时,测试冻结,如下所示:
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_sync(main, ^
{
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationAuthenticationSuccess object:nil userInfo:ret];
});
Run Code Online (Sandbox Code Playgroud)
我想知道为什么它冻结在那里,如果有人有任何提示.
Ali*_*are 55
关于冻结提示的问题的第二部分:
调用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
Run Code Online (Sandbox Code Playgroud)
[编辑]小心,dispatch_get_current_queue()仅用于调试目的而从未投入生产.实际上,dispatch_get_current_queue自iOS6.1.3起就被弃用了.
如果您处于主队列的特定情况(仅与主线程相关联),则可以[NSThread isMainThread]按@ meaning-matters的建议进行测试.
顺便问一下,你确定你需要dispatch_sync在你的情况下吗?我想稍后发送你的通知,避免阻塞直到它被发送,在你的情况下是可以接受的,所以你也可以考虑使用dispatch_async(而不是使用dispatch_sync并需要队列比较条件),这也可以避免死锁问题.
mea*_*ers 40
dispatch_get_current_queue()从iOS 6开始被弃用,并且在iOS 6.1.3的主线程上dispatch_get_current_queue() == dispatch_get_main_queue()被发现false.
在iOS 6及更高版本中,只需:
dispatch_block_t block = ^
{
<your code here>
};
if ([NSThread isMainThread])
{
block();
}
else
{
dispatch_sync(dispatch_get_main_queue(), block);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12575 次 |
| 最近记录: |