为什么我们不能在当前队列上使用dispatch_sync? [英] Why can't we use a dispatch_sync on the current queue?
问题描述
我遇到了这样一个场景:我有一个委托回调,该回调可能发生在主线程或另一个线程上,直到运行时(使用StoreKit.framework
)我才知道是哪个.
I ran into a scenario where I had a delegate callback which could occur on either the main thread or another thread, and I wouldn't know which until runtime (using StoreKit.framework
).
我还需要在该回调中更新UI代码,该代码需要在函数执行之前发生,所以我最初的想法是拥有这样的函数:
I also had UI code that I needed to update in that callback which needed to happen before the function executed, so my initial thought was to have a function like this:
-(void) someDelegateCallback:(id) sender
{
dispatch_sync(dispatch_get_main_queue(), ^{
// ui update code here
});
// code here that depends upon the UI getting updated
}
当它在后台线程上执行时,效果很好.但是,在主线程上执行时,程序将陷入死锁.
That works great, when it is executed on the background thread. However, when executed on the main thread, the program comes to a deadlock.
这对我来说似乎很有趣,如果我正确地阅读了dispatch_sync
的文档,那么我希望它可以直接执行该块,而不必担心将其调度到runloop中,如
That alone seems interesting to me, if I read the docs for dispatch_sync
right, then I would expect it to just execute the block outright, not worrying about scheduling it into the runloop, as said here:
作为一种优化,此函数在可能的情况下在当前线程上调用该块.
As an optimization, this function invokes the block on the current thread when possible.
但是,这没什么大不了的,它只是意味着要多键入一些内容,这使我采用了这种方法:
But, that's not too big of a deal, it simply means a bit more typing, which lead me to this approach:
-(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的错误,还是我在文档中缺少某些东西?
However, this seems a bit backwards. Was this a bug in the making of GCD, or is there something that I am missing in the docs?