iOS如何判断多个异步线程是否执行完毕

前言

在实际开发中有A、B、C、D异步请求,需要A、B、C、D执行完,然后去执行其他线程。有什么办法可以处理?

方法一:RunLoop

NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"A");
        CFRunLoopStop(CFRunLoopGetMain());
    }] ;
 [task resume];
 CFRunLoopRun();
 NSLog(@"B");

这里执行结果是先输出A后在输出B,注意CFRunLoopRun()的位置

方法二:GCD的group

  • 原理就是利用dispatch_group_async执行完queue会执行dispatch_group_notify回调
  • 多线程操作时这个方法使用频繁
dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_group_async(group, queue, ^{
        NSLog(@"A");
    });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"B");
    });

输出A后再输出B

方法三:dispatch_barrier_async

  • 一般使用dispatch_barrier_async, 会让barrier之前的线程执行完成之后才会执行barrier后面的操作,起到一个阻挡的作用。
 dispatch_queue_t queue =  dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        NSLog(@"A");
    });
    dispatch_async(queue, ^{
        NSLog(@"C");
    });
    dispatch_barrier_async(queue, ^{
        NSLog(@"拿到了A的值");
    });

    dispatch_async(queue, ^{
        NSLog(@"D");
    });
    dispatch_async(queue, ^{
        NSLog(@"E");
    });dispatch_async(queue, ^{
        NSLog(@"F");
    });

A、C输出顺序不固定,然后输出拿到了A的值,然后D、E、F输出顺序不固定
这里指定的并发队列是自己通过dispatch_queue_create函数创建的,如果你传的是一个串行队列或者全局并发队列,这个函数等同于dispatch_async函数

方法四:NSOperationQueue

  • 主要就是用到NSOperationQueue的一个对象方法addDependency :
  • 需要注意一点:waitUntilFinished如果是YES,必须等到queue中所有Operation执行完毕之后, 才会打D, 起到一个阻塞的作用,反之的话, D的打印顺序是随机的了,就看哪个线程跑得快了...
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    NSBlockOperation *p1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"A");
    }];
    NSBlockOperation *p2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"B");
    }];
    NSBlockOperation *p3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"C");
    }];
    [p3 addDependency:p1];
    [p1 addDependency:p2];
    // waitUntilFinished是否阻塞当前线程
    [queue addOperations:@[p1,p2,p3] waitUntilFinished:YES];
    // 如果是NO,那么这行打印就是随机的, 反之就是等A,B,C都打印完之后才执行
    NSLog(@"D");

输出C、A、B再输出D

结束

  • 相信很多的初学iOS开发人员对于这种场景习惯在success回调中再嵌套一个异步线程,嵌套固然可以达到效果,但是代码的可读性就变差了。
  • 相信你看到文章结尾你已经get到新tip了。
  • 实现的方式还有很多,如果你想到了欢迎留言。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、前言 上一篇文章iOS多线程浅汇-原理篇中整理了一些有关多线程的基本概念。本篇博文介绍的是iOS中常用的几个多...
    nuclear阅读 6,253评论 6 18
  • 欢迎大家指出文章中需要改正或者需要补充的地方,我会及时更新,非常感谢。 一. 多线程基础 1. 进程 进程是指在系...
    xx_cc阅读 12,006评论 11 70
  • 插入排序:1、最简单的排序算法。2、在增量排序中有很高的效率,比如已经存在成绩排序,要插入一个新的成绩并且排序。3...
    KPort阅读 2,732评论 0 1
  • 今天下午我们三年级一班家委会主任孙宝钧妈妈私聊我,说是在校级家委会里打听了宫明浩爸爸的策略,为了调动家长的积极性,...
    强丽阅读 1,430评论 0 0
  • 婚姻-无论谁放手,受伤的都是孩子
    miss郝阅读 1,748评论 0 0