我遇到了这样一个场景:我有一个委托(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的问题,我认为唯一明智的方法是发现问题后才发明的方法。

08-18 14:54