【发布时间】:2012-06-14 15:09:01
【问题描述】:
我遇到了一个场景,我有一个委托回调,它可能发生在主线程或另一个线程上,直到运行时我才知道是哪个(使用 StoreKit.framework)。
我还有需要在回调中更新的 UI 代码,这需要在函数执行之前发生,所以我最初的想法是有一个这样的函数:
-(void) someDelegateCallback:(id) sender
{
dispatch_sync(dispatch_get_main_queue(), ^{
// ui update code here
});
// code here that depends upon the UI getting updated
}
当它在后台线程上执行时,效果很好。但是,当在主线程上执行时,程序会陷入死锁。
仅这一点对我来说似乎很有趣,如果我正确阅读了 dispatch_sync 的文档,那么我希望它直接执行该块,而不用担心将其安排到运行循环中,如 here 所说:
作为一种优化,此函数在可能的情况下调用当前线程上的块。
但是,这没什么大不了的,它只是意味着更多的打字,这导致我采用这种方法:
-(void) someDelegateCallBack:(id) sender
{
dispatch_block_t onMain = ^{
// update UI code here
};
if (dispatch_get_current_queue() == dispatch_get_main_queue())
onMain();
else
dispatch_sync(dispatch_get_main_queue(), onMain);
}
但是,这似乎有点倒退。这是 GCD 制作中的错误,还是我在文档中遗漏了什么?
【问题讨论】:
-
dispatch_get_current_queue()现在已弃用。检测主队列的方法是NSThread.isMainThread()(Swift) 或 [NSThread isMainThread] (Objective-C) -
@jtbandes 将问题标记为重复时请小心。这个问题显然比您链接的问题更老,并且活动更多,也许它们应该在相反的方向关闭。
-
@RichardJ.RossIII:我确实考虑过;我欺骗它的 IMO 是一个更容易理解的问题,答案更全面。这个话题在meta.stackoverflow.com/questions/315472/…讨论
标签: objective-c multithreading objective-c-blocks grand-central-dispatch