美文网首页
GCD实现多个任务完成后再执行某一任务的正确姿势

GCD实现多个任务完成后再执行某一任务的正确姿势

作者: 本源道人 | 来源:发表于2017-09-25 20:45 被阅读33次

关于这个问题,网上的教程很多,其中绝大多数都没有讲到在实际使用过程中会遇到的坑。所以,在使用之初可能会遇到一些困惑。比如:我明明已经按照给出的教程实现相关任务,为什么不是预想的结果呢?(想要最后执行的任务却不是最后执行,同步任务这里不予考虑)

使用GCD实现多个任务完成再执行另一任务的常见方法形如:

    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);

    // 任务A
    dispatch_group_async(group, globalQueue, ^{
        sleep(5);
        NSLog(@"A");
    });
    // 任务B
    dispatch_group_async(group, globalQueue, ^{
        NSLog(@"B");
    });

    // 任务over
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"over");
    });

在上面的方法中,运行结果是 B->A->over。简直完美!看起来没有问题啊,我甚至是让A睡了5秒钟,任务over还是最后执行。但。。。但是,为什么实际开发过程中,就会出现问题呢?

来看看出问题的一个例子:

    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
    
    // 任务A
    dispatch_group_async(group, globalQueue, ^{
        sleep(2);
        NSLog(@"A");
        
        // 任务C
        dispatch_async(globalQueue, ^{
            sleep(5);
            NSLog(@"C");
        });
    });
    // 任务B
    dispatch_group_async(group, globalQueue, ^{
        NSLog(@"B");
        
        // 任务D
        dispatch_async(globalQueue, ^{
            sleep(2);
            NSLog(@"D");
        });
    });
    
    // 任务over
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"over");
    });

它的执行结果为:B->D->A->over->C。😓为什么呢?因为任务C/D不归调度组管啊。那我们把它加入调度组呢?

代码变成了这样:

dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
    
    // 任务A
    dispatch_group_async(group, globalQueue, ^{
        sleep(2);
        NSLog(@"A");
        
        // 任务C
        dispatch_group_async(group, globalQueue, ^{
            sleep(5);
            NSLog(@"C");
        });
    });
    // 任务B
    dispatch_group_async(group, globalQueue, ^{
        NSLog(@"B");
        
        // 任务D
        dispatch_group_async(group, globalQueue, ^{
            sleep(2);
            NSLog(@"D");
        });
    });
    
    // 任务over
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"over");
    });

执行结果为:B->A->D->C->over。这样以来,结果就是我们想要的了。任务over是最后执行的。然而,事情还没完。想象一下,我们要做一个网络请求,比如使用AFN。把任务C、D换成两个异步网络请求,这个时候,就没法使用上述方法把任务C/D加入调度组,因为AFN自己管理多线程任务了。怎么办呢?

可以尝试这么搞:

    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
    
    // 任务A
    dispatch_group_async(group, globalQueue, ^{
        sleep(2);
        NSLog(@"A");
        
        // 任务C
        dispatch_group_enter(group);
        dispatch_async(globalQueue, ^{
            sleep(5);
            NSLog(@"C");
            
            dispatch_group_leave(group);
        });
    });
    // 任务B
    dispatch_group_async(group, globalQueue, ^{
        NSLog(@"B");
        
        // 任务D
        dispatch_group_enter(group);
        dispatch_async(globalQueue, ^{
            sleep(2);
            NSLog(@"D");
            
            dispatch_group_leave(group);
        });
    });
    
    // 任务over
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"over");
    });

在block之前入组,在block执行完成后出组。dispatch_group_enter()dispatch_group_leave()必须配套使用。

写在最后:或许还存在其他的问题吧?欢迎补充!万分感谢!

相关文章

  • GCD实现等待多个异步任务完成

    开发过程中可能需要实现多个异步任务完成后再执行下一步任务,GCD实现如下:

  • GCD实现多个任务完成后再执行某一任务的正确姿势

    关于这个问题,网上的教程很多,其中绝大多数都没有讲到在实际使用过程中会遇到的坑。所以,在使用之初可能会遇到一些困惑...

  • iOS开发中GCD普遍使用

    1.全局队列和主队 2.串行队列和并行队列 串行队列 并行队列 3.多个线程子任务完成后再执行某一个任务,GCD线...

  • GCD-调度组

    如果有多个执行任务,我们希望他们都执行完成后执行某一操作,可以采用调度组。 1、创建调度组: 2、创建并发任务: ...

  • iOS 多个任务完成后再执行

    在开发中,我们很容易遇到这样的需求,需要我们同时做多个网络请求,所有网络请求都完成后才能进行下一步的操作。如下载多...

  • GCD 多个网络请求/任务并发或顺序执行

    GCD的使用:多个网络请求/任务并发或顺序执行,所有的网络请求/任务都结束之后再执行数据操作。 Demo地址:De...

  • 并行ajax请求

    这个是几次面试遇到的问题 要求就是,多个ajax同时发出等全部完成后再执行其它任务。如何实现 使用promise很...

  • dispatch_group_t 的使用

    多个任务并发执行, 完成后在做某个事情

  • Kotlin:该如何实现多线程同步?

    问题背景需执行多线程任务:任务1、任务2并行执行;等全部执行完成后,执行任务3。 实现方式「多线程同步」。Kotl...

  • Flutter异步

    多个任务完成后执行下一个任务Future printUserName() async {List r...

网友评论

      本文标题:GCD实现多个任务完成后再执行某一任务的正确姿势

      本文链接:https://www.haomeiwen.com/subject/feodextx.html