我需要在主队列上同步调度一个块。我不知道我当前是否在主线程上运行。天真的解决方案如下所示:
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);
}
这可行,但很丑。在我至少将其隐藏在某些自定义函数后面之前,是否有更好的解决方案来解决这个问题?我强调,我无法承担异步分派块的费用 - 应用程序处于异步分派块执行“太晚”的情况。
我需要在我的 Mac 和 iOS 应用程序中经常使用类似的东西,所以我使用以下辅助函数(最初在这个答案 https://stackoverflow.com/a/5226271/19679):
void runOnMainQueueWithoutDeadlocking(void (^block)(void))
{
if ([NSThread isMainThread])
{
block();
}
else
{
dispatch_sync(dispatch_get_main_queue(), block);
}
}
您通过以下方式致电
runOnMainQueueWithoutDeadlocking(^{
//Do stuff
});
这几乎就是您上面描述的过程,我已经与其他几位开发人员交谈过,他们为自己独立制作了类似的东西。
I used [NSThread isMainThread]
而不是检查dispatch_get_current_queue()
,因为该函数的注意事项部分 http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/dispatch_get_current_queue.3.html曾经警告不要使用它进行身份测试和该调用在 iOS 6 中已被弃用 https://stackoverflow.com/questions/13237417/alternatives-to-dispatch-get-current-queue-for-completion-blocks-in-ios-6.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)