我遇到了这样一个场景:我有一个委托回调,它可能发生在主线程或另一个线程上,直到运行时我才知道是哪个(使用StoreKit.framework
).
我还需要在回调中更新UI代码,这需要在函数执行之前进行,所以我最初的 idea 是有这样一个函数:
-(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
的文档,那么我希望它直接执行块,而不用担心将其调度到runloop中,如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制作过程中的一个错误,还是我在文档中遗漏了什么?