程序员

dispatch_group_async

2018-01-29  本文已影响64人  _清墨

需求:有5个任务,前面4个都是不耗时的,执行顺序无要求,第5个任务得在前4个任务都完成后执行。

实现这样的需求,办法可以参照https://www.jianshu.com/p/fb4fb80aefb8,也可以根据我写的上一篇文章,使用串行队列异步执行,这里我们使用dispatch_group_async。

dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create("usedQueue", DISPATCH_QUEUE_CONCURRENT); //这里要是换成串行队列,则会按顺序执行了,并不要求顺序。
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"task1");
        NSLog(@"task1---%@",[NSThread currentThread]);
    });
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"task2");
        NSLog(@"task2---%@",[NSThread currentThread]);
    });
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"task3");
        NSLog(@"task3---%@",[NSThread currentThread]);
    });
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"task4");
        NSLog(@"task4---%@",[NSThread currentThread]);
    });
    
    //这里若是需要修改UI,队列要写成主队列
    dispatch_group_notify(group, queue, ^{
        NSLog(@"task5");
        NSLog(@"task5---%@",[NSThread currentThread]);
    });

运行结果:

2018-01-29 14:23:03.039 GCD[72969:4081287] task1
2018-01-29 14:23:03.039 GCD[72969:4081284] task2
2018-01-29 14:23:03.039 GCD[72969:4081285] task3
2018-01-29 14:23:03.039 GCD[72969:4081306] task4
2018-01-29 14:23:03.040 GCD[72969:4081287] task1---<NSThread: 0x608000078bc0>{number = 3, name = (null)}
2018-01-29 14:23:03.040 GCD[72969:4081284] task2---<NSThread: 0x608000078c80>{number = 4, name = (null)}
2018-01-29 14:23:03.042 GCD[72969:4081285] task3---<NSThread: 0x60000007be40>{number = 5, name = (null)}
2018-01-29 14:23:03.042 GCD[72969:4081306] task4---<NSThread: 0x600000076340>{number = 6, name = (null)}
2018-01-29 14:23:03.045 GCD[72969:4081253] task5
2018-01-29 14:23:03.045 GCD[72969:4081253] task5---<NSThread: 0x60800006f2c0>{number = 1, name = main}
2018-01-29 14:44:07.522 GCD[73068:4103517] task2
2018-01-29 14:44:07.522 GCD[73068:4103516] task1
2018-01-29 14:44:07.522 GCD[73068:4103536] task3
2018-01-29 14:44:07.522 GCD[73068:4103519] task4
2018-01-29 14:44:07.523 GCD[73068:4103517] task2---<NSThread: 0x600000078140>{number = 3, name = (null)}
2018-01-29 14:44:07.523 GCD[73068:4103516] task1---<NSThread: 0x608000079380>{number = 4, name = (null)}
2018-01-29 14:44:07.523 GCD[73068:4103536] task3---<NSThread: 0x600000078180>{number = 5, name = (null)}
2018-01-29 14:44:07.523 GCD[73068:4103519] task4---<NSThread: 0x6000000784c0>{number = 6, name = (null)}
2018-01-29 14:44:07.529 GCD[73068:4103471] task5
2018-01-29 14:44:07.529 GCD[73068:4103471] task5---<NSThread: 0x60800006f000>{number = 1, name = main}

结果是满足我们需求的,但若是耗时任务的网络请求(同步的忽略如[NSData dataWithContentsOfURL:]),这样的方式还行吗?

dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create("usedQueue", DISPATCH_QUEUE_CONCURRENT);
    
    NSString *str = @"http://www.jianshu.com/p/6930f335adba";
    NSURL *url = [NSURL URLWithString:str];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLSession *session = [NSURLSession sharedSession];
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"第一个网络请求开始");
        NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            
            NSLog(@"第一个网络请求完成");
            
        }];
        
        [task resume];
    });
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"第二个网络请求开始");
        NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            
            NSLog(@"第二个网络请求完成");
            
        }];
        
        [task resume];
    });
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"第三个网络请求开始");
        NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            
            NSLog(@"第三个网络请求完成");
            
        }];
        
        [task resume];
    });
    
    //这里若是需要修改UI,队列要写成主队列
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"end");
    });

运行结果:

2018-01-29 14:49:39.270 GCD[73103:4110191] 第一个网络请求开始
2018-01-29 14:49:39.270 GCD[73103:4110207] 第二个网络请求开始
2018-01-29 14:49:39.270 GCD[73103:4110188] 第三个网络请求开始
2018-01-29 14:49:39.281 GCD[73103:4110145] end
2018-01-29 14:49:39.540 GCD[73103:4110189] 第二个网络请求完成
2018-01-29 14:49:39.598 GCD[73103:4110191] 第三个网络请求完成
2018-01-29 14:49:39.606 GCD[73103:4110189] 第一个网络请求完成

可以看出,若是需要网络请求完再执行end的话,这样是满足不了的,这是因为对于网络请求来说,在请求发出时他就算执行完毕了,并不会等待回调。所以要实现:iOS多个网络请求完成后执行下一步 还请参考我的这篇文章https://www.jianshu.com/p/fb4fb80aefb8

上一篇下一篇

猜你喜欢

热点阅读