为什么我们不能在当前队列上使用dispatch_sync? [英] Why can't we use a dispatch_sync on the current queue?

查看:90
本文介绍了为什么我们不能在当前队列上使用dispatch_sync?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了这样一个场景:我有一个委托回调,该回调可能发生在主线程或另一个线程上,直到运行时(使用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?

推荐答案

我在

请勿从正在执行的任务中调用dispatch_sync函数 与传递给函数调用的队列相同.这样做会 使队列死锁.如果您需要分派到当前队列,请执行 因此异步使用dispatch_async函数.

Do not call the dispatch_sync function from a task that is executing on the same queue that you pass to your function call. Doing so will deadlock the queue. If you need to dispatch to the current queue, do so asynchronously using the dispatch_async function.

此外,我点击了您提供的链接,并且在 dispatch_sync 的说明中,我读到了这篇文章:

Also, I followed the link that you provided and in the description of dispatch_sync I read this:

调用此函数并定位当前队列会导致死锁.

Calling this function and targeting the current queue results in deadlock.

所以我认为这不是GCD的问题,我认为唯一明智的方法是发现问题后发明的方法.

So I don't think it's a problem with GCD, I think the only sensible approach is the one you invented after discovering the problem.

这篇关于为什么我们不能在当前队列上使用dispatch_sync?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆