如果我嵌套了dispatch_async调用,会发生什么? [英] What will happen if I have nested dispatch_async calls?

查看:102
本文介绍了如果我嵌套了dispatch_async调用,会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能是一个愚蠢的问题,但我需要自己询问并清除它。

It may be a dumb question but I need to ask and clear this up for myself.

要将一个块提交到队列中执行,请使用函数 dispatch_sync dispatch_async 。它们都将队列和块作为参数。 dispatch_async 立即返回,异步运行块,而 dispatch_sync 阻止执行,直到提供的块返回。以下是一些情况:

To submit a block onto a queue for execution, use the functions dispatch_sync and dispatch_async. They both take a queue and a block as parameters. dispatch_async returns immediately, running the block asynchronously, while dispatch_sync blocks execution until the provided block returns. Here are some situations:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);    
dispatch_async(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_async(queue, ^{
        NSLog(@"this is statement1");

    });
});



情况2



Situation 2

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);    
dispatch_sync(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_sync(queue, ^{
        NSLog(@"this is statement1");

    });
});



情况3



Situation 3

{
    [super viewDidLoad];
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);    
    dispatch_async(queue, ^{
        [self goDoSomethingLongAndInvolved];
        dispatch_sync(queue, ^{
            NSLog(@"this is statement1");

        });
    });



情况4



Situation 4

{
    [super viewDidLoad];
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);    
    dispatch_sync(queue, ^{
        [self goDoSomethingLongAndInvolved];
        dispatch_async(queue, ^{
            NSLog(@"this is statement1");

        });
    });

}

goDoSomethingLongAndInvolved

-(void)goDoSomethingLongAndInvolved {
    NSLog(@"goDoSomethingLongAndInvolved");
}

我试图在Xcode中运行它们但我看不出它们的区别。

I tried to run them in Xcode but I cant see the difference at all.

所以我的问题是:


  1. 这些情况之间的主要区别是什么?

  2. 如果我用 dispatch_get_main_queue()替换 queue 怎么办?

  1. What's the main difference between these situations?
  2. What if I replace queue with dispatch_get_main_queue()?


推荐答案

dispatch_sync 语句一直等到块它涵盖了完全执行。 dispatch_async 立即返回并继续执行下一行代码,因此内部的所有内容都是并行发生的。

The dispatch_sync statement waits until the block it covers is executed completely. dispatch_async returns immediately and proceeds to the next line of code, so everything inside is happening in parallel.

如果 queue 是您自己创建的串行队列,那么:

If queue was a serial queue created by yourself, then:

情况1 - 根块立即返回。在里面它等待[self go ....],然后转到dispatch_async,它也会立即返回。

Situation 1 - The root block returns immediately. Inside it waits for [self go....], and then goes to dispatch_async, which returns immediately as well.

情况2 - 如果 queue 是一个串行队列,然后会有一个死锁,因为它会等待自己完成执行。由于您正在处理异步,因此该块将并行执行。 (谢谢,@ Ken Thomases)

Situation 2 - If queue was a serial queue, then there would be a dead lock since it will wait for itself to finish executing. Since you are dealing with asynchronous one, that block will be executed in parallel. (Thanks, @Ken Thomases)

情况3 - 此处不需要 dispatch_sync 。它导致死锁。

Situation 3 - No need in dispatch_sync here. It causes the deadlock.

情况4 - 等待[self ...],然后立即返回。

Situation 4 - Waits for [self ...], then returns immediately.

如果用主队列替换队列,请记住不要 dispatch_sync 在主队列上,因为它会导致死锁(如果不是从主线程调度则不会,感谢@Ken Thomases)。

If you replace the queue with main queue, then remember to not dispatch_sync on main queue, because it will cause a deadlock (it will not if dispatched not from main thread, thanks @Ken Thomases).

为了更好地理解它,请用以下代码替换你的函数:

To understand it better, replace your function with:

-(void)goDoSomethingLongAndInvolved:(NSString *)message {
    for(int i = 0; i < 50; ++i) {
        NSLog(@"%@ -> %d", message, i); 
    }
}

你会清楚地看到每次发生的事情,无论是它等待与否。祝你好运。

You will clearly see what's going on every time, whether it waits or not. Good luck.

这篇关于如果我嵌套了dispatch_async调用,会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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