我遇到了这样一个场景:我有一个委托(delegate)回调,它可能发生在主线程或另一个线程上,直到运行时我才知道是哪个(使用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时的错误吗?还是我在文档中缺少某些内容?
最佳答案
我在the documentation (last chapter)中找到了这个:
另外,我遵循了您提供的链接,在 dispatch_sync 的描述中,我读到了以下内容:
因此,我认为这不是GCD的问题,我认为唯一明智的方法是发现问题后才发明的方法。