GCD多线程应用

2017-08-09  本文已影响0人  a315c2a13dc5

概念

在GCD中有两个重要的概念:任务和队列。

任务

所要执行的操作。任务有两种执行方式:同步执行和异步执行。

队列

用于存放任务。队列有两种:串行队列和并发队列。

GCD的多线程使用

使用步骤

  1. 创建队列
  2. 向队列中添加任务:
    • 通过dispatch_async进行异步添加
    • 通过dispatch_sync进行同步添加

使用方式

由于存在不同的队列和任务执行方式,因此有多种组合方式来使用。

  1. 并发队列+同步执行
- (void)test {
    NSLog(@"=============begin") ;
    dispatch_queue_t myQueue = dispatch_queue_create("com.appress.myQueue",DISPATCH_QUEUE_CONCURRENT) ;
    dispatch_sync(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"1=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_sync(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"2=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_sync(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"3=========%@",[NSThread currentThread]) ;
        }
    }) ;
    NSLog(@"=============end") ;
}

打印结果为:

2017-05-03 14:59:35.976 test[1022:28719] =============begin
2017-05-03 14:59:35.977 test[1022:28719] 1=========<NSThread: 0x600000071240>{number = 1, name = main}
2017-05-03 14:59:35.977 test[1022:28719] 1=========<NSThread: 0x600000071240>{number = 1, name = main}
2017-05-03 14:59:35.977 test[1022:28719] 2=========<NSThread: 0x600000071240>{number = 1, name = main}
2017-05-03 14:59:35.977 test[1022:28719] 2=========<NSThread: 0x600000071240>{number = 1, name = main}
2017-05-03 14:59:35.977 test[1022:28719] 3=========<NSThread: 0x600000071240>{number = 1, name = main}
2017-05-03 14:59:35.977 test[1022:28719] 3=========<NSThread: 0x600000071240>{number = 1, name = main}
2017-05-03 14:59:35.978 test[1022:28719] =============end
  1. 并发队列+异步执行
- (void)test {
    NSLog(@"=============begin") ;
    dispatch_queue_t myQueue = dispatch_queue_create("com.appress.myQueue",DISPATCH_QUEUE_CONCURRENT) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"1=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"2=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"3=========%@",[NSThread currentThread]) ;
        }
    }) ;
    NSLog(@"=============end") ;
}

打印结果为:

2017-05-03 15:04:37.047 test[1064:39634] =============begin
2017-05-03 15:04:37.047 test[1064:39634] =============end
2017-05-03 15:04:37.048 test[1064:39685] 2=========<NSThread: 0x60800007bc00>{number = 4, name = (null)}
2017-05-03 15:04:37.048 test[1064:39690] 1=========<NSThread: 0x60800007bd00>{number = 3, name = (null)}
2017-05-03 15:04:37.048 test[1064:39684] 3=========<NSThread: 0x60800007bfc0>{number = 5, name = (null)}
2017-05-03 15:04:37.048 test[1064:39685] 2=========<NSThread: 0x60800007bc00>{number = 4, name = (null)}
2017-05-03 15:04:37.048 test[1064:39690] 1=========<NSThread: 0x60800007bd00>{number = 3, name = (null)}
2017-05-03 15:04:37.049 test[1064:39684] 3=========<NSThread: 0x60800007bfc0>{number = 5, name = (null)}
  1. 串行队列+同步执行
- (void)test {
    NSLog(@"=============begin") ;
    dispatch_queue_t myQueue = dispatch_queue_create("com.appress.myQueue",nil) ;
    dispatch_sync(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"1=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_sync(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"2=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_sync(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"3=========%@",[NSThread currentThread]) ;
        }
    }) ;
    NSLog(@"=============end") ;
}

打印结果为:

2017-05-03 15:10:33.497 test[1133:50233] =============begin
2017-05-03 15:10:33.497 test[1133:50233] 1=========<NSThread: 0x608000063800>{number = 1, name = main}
2017-05-03 15:10:33.498 test[1133:50233] 1=========<NSThread: 0x608000063800>{number = 1, name = main}
2017-05-03 15:10:33.498 test[1133:50233] 2=========<NSThread: 0x608000063800>{number = 1, name = main}
2017-05-03 15:10:33.498 test[1133:50233] 2=========<NSThread: 0x608000063800>{number = 1, name = main}
2017-05-03 15:10:33.499 test[1133:50233] 3=========<NSThread: 0x608000063800>{number = 1, name = main}
2017-05-03 15:10:33.499 test[1133:50233] 3=========<NSThread: 0x608000063800>{number = 1, name = main}
2017-05-03 15:10:33.499 test[1133:50233] =============end
  1. 串行队列+异步执行
- (void)test {
    NSLog(@"=============begin") ;
    dispatch_queue_t myQueue = dispatch_queue_create("com.appress.myQueue",nil) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"1=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"2=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"3=========%@",[NSThread currentThread]) ;
        }
    }) ;
    NSLog(@"=============end") ;
}

打印结果为:

2017-05-03 15:13:35.786 test[1168:56495] =============begin
2017-05-03 15:13:35.787 test[1168:56495] =============end
2017-05-03 15:13:35.787 test[1168:56601] 1=========<NSThread: 0x608000270200>{number = 3, name = (null)}
2017-05-03 15:13:35.787 test[1168:56601] 1=========<NSThread: 0x608000270200>{number = 3, name = (null)}
2017-05-03 15:13:35.787 test[1168:56601] 2=========<NSThread: 0x608000270200>{number = 3, name = (null)}
2017-05-03 15:13:35.787 test[1168:56601] 2=========<NSThread: 0x608000270200>{number = 3, name = (null)}
2017-05-03 15:13:35.788 test[1168:56601] 3=========<NSThread: 0x608000270200>{number = 3, name = (null)}
2017-05-03 15:13:35.788 test[1168:56601] 3=========<NSThread: 0x608000270200>{number = 3, name = (null)}
  1. 主队列+同步执行
NSLog(@"=============begin") ;
    dispatch_queue_t myQueue = dispatch_get_main_queue() ;
    dispatch_sync(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"1=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_sync(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"2=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_sync(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"3=========%@",[NSThread currentThread]) ;
        }
    }) ;
    NSLog(@"=============end") ;

如果在主线程中采用该方式会出现互等卡住的情况。

在子线程中执行的打印结果为:

2017-05-03 15:34:40.630 test[1279:89558] =============begin
2017-05-03 15:34:40.634 test[1279:89501] 1=========<NSThread: 0x60000006e3c0>{number = 1, name = main}
2017-05-03 15:34:40.635 test[1279:89501] 1=========<NSThread: 0x60000006e3c0>{number = 1, name = main}
2017-05-03 15:34:40.636 test[1279:89501] 2=========<NSThread: 0x60000006e3c0>{number = 1, name = main}
2017-05-03 15:34:40.636 test[1279:89501] 2=========<NSThread: 0x60000006e3c0>{number = 1, name = main}
2017-05-03 15:34:40.636 test[1279:89501] 3=========<NSThread: 0x60000006e3c0>{number = 1, name = main}
2017-05-03 15:34:40.636 test[1279:89501] 3=========<NSThread: 0x60000006e3c0>{number = 1, name = main}
2017-05-03 15:34:40.637 test[1279:89558] =============end
  1. 主队列+异步执行
- (void)test {
    NSLog(@"=============begin") ;
    dispatch_queue_t myQueue = dispatch_get_main_queue() ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"1=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"2=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 2; i++) {
            NSLog(@"3=========%@",[NSThread currentThread]) ;
        }
    }) ;
    NSLog(@"=============end") ;
}

打印结果为:

2017-05-03 15:36:10.336 test[1312:93448] =============begin
2017-05-03 15:36:10.337 test[1312:93448] =============end
2017-05-03 15:36:10.347 test[1312:93448] 1=========<NSThread: 0x600000064c80>{number = 1, name = main}
2017-05-03 15:36:10.348 test[1312:93448] 1=========<NSThread: 0x600000064c80>{number = 1, name = main}
2017-05-03 15:36:10.352 test[1312:93448] 2=========<NSThread: 0x600000064c80>{number = 1, name = main}
2017-05-03 15:36:10.358 test[1312:93448] 2=========<NSThread: 0x600000064c80>{number = 1, name = main}
2017-05-03 15:36:10.359 test[1312:93448] 3=========<NSThread: 0x600000064c80>{number = 1, name = main}
2017-05-03 15:36:10.359 test[1312:93448] 3=========<NSThread: 0x600000064c80>{number = 1, name = main}

总结如下:

队列 并行队列 串行队列 主队列
同步(sync) 没有开启新线程,串行执行任务 没有开启新线程,串行执行任务 没有开启新线程,串行执行任务
异步(async) 有开启新线程,并发执行任务 有开启新线程,串行执行任务 没有开启新线程,串行执行任务

当任务队列为非主队列时,只有异步执行才会开启新线程。如果是并发队列,会开启多条线程,如果是串行队列, 只会开启一条线程。 其他情况下(包括主队列) 都不会开启新线程,并且是串行执行任务。

GCD的其他使用

GCD 栅栏函数

在异步执行任务的过程中,有时候需要控制任务执行的顺序:在第一组任务执行完成后再执行第二组任务,可以通过GCD的栅栏函数dispatch_barrier_async来实现。当栅栏函数执行完成后才会执行后面的任务。

使用

添加栅栏函数前:

- (void)test {
    NSLog(@"=============begin") ;
    dispatch_queue_t myQueue = dispatch_queue_create("com.appress.myQueue",DISPATCH_QUEUE_CONCURRENT) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 3; i++) {
            NSLog(@"1=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 3; i++) {
            NSLog(@"2=========%@",[NSThread currentThread]) ;
        }
    }) ;
//    dispatch_barrier_async(myQueue, ^{
//        NSLog(@"++++++++++++++++++++++++++++++++++++++++") ;
//    }) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 3; i++) {
            NSLog(@"3=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 3; i++) {
            NSLog(@"4=========%@",[NSThread currentThread]) ;
        }
    }) ;
    NSLog(@"=============end") ;
}

打印结果为:

2017-05-08 15:37:00.970 test[14150:286911] =============begin
2017-05-08 15:37:00.970 test[14150:286911] =============end
2017-05-08 15:37:00.970 test[14150:286950] 2=========<NSThread: 0x60000026b480>{number = 4, name = (null)}
2017-05-08 15:37:00.970 test[14150:286951] 1=========<NSThread: 0x608000267680>{number = 3, name = (null)}
2017-05-08 15:37:00.970 test[14150:286971] 4=========<NSThread: 0x60000026bac0>{number = 6, name = (null)}
2017-05-08 15:37:00.970 test[14150:286953] 3=========<NSThread: 0x60000026b4c0>{number = 5, name = (null)}
2017-05-08 15:37:00.971 test[14150:286950] 2=========<NSThread: 0x60000026b480>{number = 4, name = (null)}
2017-05-08 15:37:00.971 test[14150:286951] 1=========<NSThread: 0x608000267680>{number = 3, name = (null)}
2017-05-08 15:37:00.971 test[14150:286971] 4=========<NSThread: 0x60000026bac0>{number = 6, name = (null)}
2017-05-08 15:37:00.971 test[14150:286953] 3=========<NSThread: 0x60000026b4c0>{number = 5, name = (null)}
2017-05-08 15:37:00.971 test[14150:286950] 2=========<NSThread: 0x60000026b480>{number = 4, name = (null)}
2017-05-08 15:37:00.971 test[14150:286951] 1=========<NSThread: 0x608000267680>{number = 3, name = (null)}
2017-05-08 15:37:00.972 test[14150:286953] 3=========<NSThread: 0x60000026b4c0>{number = 5, name = (null)}
2017-05-08 15:37:00.972 test[14150:286971] 4=========<NSThread: 0x60000026bac0>{number = 6, name = (null)}

添加栅栏函数后:

- (void)test {
    NSLog(@"=============begin") ;
    dispatch_queue_t myQueue = dispatch_queue_create("com.appress.myQueue",DISPATCH_QUEUE_CONCURRENT) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 3; i++) {
            NSLog(@"1=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 3; i++) {
            NSLog(@"2=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_barrier_async(myQueue, ^{
        NSLog(@"++++++++++++++++++++++++++++++++++++++++") ;
    }) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 3; i++) {
            NSLog(@"3=========%@",[NSThread currentThread]) ;
        }
    }) ;
    dispatch_async(myQueue, ^{
        for(int i = 0; i < 3; i++) {
            NSLog(@"4=========%@",[NSThread currentThread]) ;
        }
    }) ;
    NSLog(@"=============end") ;
}

打印结果为:

2017-05-08 16:02:47.255 test[14241:316852] =============begin
2017-05-08 16:02:47.256 test[14241:316852] =============end
2017-05-08 16:02:47.256 test[14241:316986] 1=========<NSThread: 0x60000006f440>{number = 3, name = (null)}
2017-05-08 16:02:47.256 test[14241:316983] 2=========<NSThread: 0x60800006c2c0>{number = 4, name = (null)}
2017-05-08 16:02:47.256 test[14241:316986] 1=========<NSThread: 0x60000006f440>{number = 3, name = (null)}
2017-05-08 16:02:47.256 test[14241:316983] 2=========<NSThread: 0x60800006c2c0>{number = 4, name = (null)}
2017-05-08 16:02:47.256 test[14241:316986] 1=========<NSThread: 0x60000006f440>{number = 3, name = (null)}
2017-05-08 16:02:47.257 test[14241:316983] 2=========<NSThread: 0x60800006c2c0>{number = 4, name = (null)}
2017-05-08 16:02:47.257 test[14241:316983] ++++++++++++++++++++++++++++++++++++++++
2017-05-08 16:02:47.257 test[14241:316983] 3=========<NSThread: 0x60800006c2c0>{number = 4, name = (null)}
2017-05-08 16:02:47.257 test[14241:316986] 4=========<NSThread: 0x60000006f440>{number = 3, name = (null)}
2017-05-08 16:02:47.257 test[14241:316983] 3=========<NSThread: 0x60800006c2c0>{number = 4, name = (null)}
2017-05-08 16:02:47.257 test[14241:316986] 4=========<NSThread: 0x60000006f440>{number = 3, name = (null)}
2017-05-08 16:02:47.257 test[14241:316983] 3=========<NSThread: 0x60800006c2c0>{number = 4, name = (null)}
2017-05-08 16:02:47.258 test[14241:316986] 4=========<NSThread: 0x60000006f440>{number = 3, name = (null)}

注意

GCD的迭代

使用

dispatch_apply(迭代次数, 线程队列(并发队列), ^(size_t index索引) {
       执行任务 ;
}) ;

注意

GCD队列组

异步执行多个耗时操作,当所有操作都执行完毕后再执行某一操作。可以通过使用GCD队列组来实现。

使用

NSLog(@"===============begin") ;
dispatch_group_t group = dispatch_group_create() ;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) ;
dispatch_group_async(group, queue, ^{
    for(int i = 0 ; i < 4 ; i ++) {
        NSLog(@"1===============%@",[NSThread currentThread]) ;
    }
}) ;
dispatch_group_async(group, queue, ^{
    for(int i = 0 ; i < 4 ; i ++) {
        NSLog(@"2===============%@",[NSThread currentThread]) ;
    }
}) ;
dispatch_group_async(group, queue, ^{
    for(int i = 0 ; i < 4 ; i ++) {
        NSLog(@"3===============%@",[NSThread currentThread]) ;
    }
}) ;
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    NSLog(@"===============end") ;
}) ;

打印结果为:

2017-08-08 13:36:21.124 GCD[3643:200121] ===============begin
2017-08-08 13:36:21.125 GCD[3643:200159] 1===============<NSThread: 0x60000007f2c0>{number = 3, name = (null)}
2017-08-08 13:36:21.125 GCD[3643:200156] 3===============<NSThread: 0x608000267100>{number = 5, name = (null)}
2017-08-08 13:36:21.125 GCD[3643:200157] 2===============<NSThread: 0x60800007cac0>{number = 4, name = (null)}
2017-08-08 13:36:21.125 GCD[3643:200159] 1===============<NSThread: 0x60000007f2c0>{number = 3, name = (null)}
2017-08-08 13:36:21.125 GCD[3643:200156] 3===============<NSThread: 0x608000267100>{number = 5, name = (null)}
2017-08-08 13:36:21.125 GCD[3643:200157] 2===============<NSThread: 0x60800007cac0>{number = 4, name = (null)}
2017-08-08 13:36:21.125 GCD[3643:200159] 1===============<NSThread: 0x60000007f2c0>{number = 3, name = (null)}
2017-08-08 13:36:21.125 GCD[3643:200156] 3===============<NSThread: 0x608000267100>{number = 5, name = (null)}
2017-08-08 13:36:21.126 GCD[3643:200157] 2===============<NSThread: 0x60800007cac0>{number = 4, name = (null)}
2017-08-08 13:36:21.126 GCD[3643:200159] 1===============<NSThread: 0x60000007f2c0>{number = 3, name = (null)}
2017-08-08 13:36:21.126 GCD[3643:200156] 3===============<NSThread: 0x608000267100>{number = 5, name = (null)}
2017-08-08 13:36:21.126 GCD[3643:200157] 2===============<NSThread: 0x60800007cac0>{number = 4, name = (null)}
2017-08-08 13:36:21.132 GCD[3643:200121] ===============end

如果dispatch_group_async的操作中有延时回调,那么在所有回调完成前就会执行dispatch_group_notify

typedef void (^resultBlock) () ;
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"===============begin") ;
    dispatch_group_t group = dispatch_group_create() ;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) ;
    dispatch_group_async(group, queue, ^{
        [self testWithBlock:^{
            for(int i = 0 ; i < 4 ; i ++) {
                NSLog(@"1===============%@",[NSThread currentThread]) ;
            }
        }] ;
    }) ;
    dispatch_group_async(group, queue, ^{
        [self testWithBlock:^{
            for(int i = 0 ; i < 4 ; i ++) {
                NSLog(@"2===============%@",[NSThread currentThread]) ;
            }
        }] ;

    }) ;
    dispatch_group_async(group, queue, ^{
        [self testWithBlock:^{
            for(int i = 0 ; i < 4 ; i ++) {
                NSLog(@"3===============%@",[NSThread currentThread]) ;
            }
        }] ;
    }) ;
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"===============end") ;
    }) ;
}

- (void)testWithBlock:(resultBlock)block {
    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0*NSEC_PER_SEC)) ;
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT) ;
    dispatch_after(time, queue, ^{
        block() ;
    }) ;
}

打印结果为:

2017-08-08 14:40:25.811 GCD[16467:291922] ===============begin
2017-08-08 14:40:26.048 GCD[16467:291922] ===============end
2017-08-08 14:40:28.007 GCD[16467:291980] 1===============<NSThread: 0x60000007c900>{number = 3, name = (null)}
2017-08-08 14:40:28.007 GCD[16467:291979] 3===============<NSThread: 0x608000262100>{number = 4, name = (null)}
2017-08-08 14:40:28.007 GCD[16467:291982] 2===============<NSThread: 0x60000007c340>{number = 5, name = (null)}
2017-08-08 14:40:28.008 GCD[16467:291979] 3===============<NSThread: 0x608000262100>{number = 4, name = (null)}
2017-08-08 14:40:28.008 GCD[16467:291980] 1===============<NSThread: 0x60000007c900>{number = 3, name = (null)}
2017-08-08 14:40:28.008 GCD[16467:291982] 2===============<NSThread: 0x60000007c340>{number = 5, name = (null)}
2017-08-08 14:40:28.008 GCD[16467:291979] 3===============<NSThread: 0x608000262100>{number = 4, name = (null)}
2017-08-08 14:40:28.008 GCD[16467:291980] 1===============<NSThread: 0x60000007c900>{number = 3, name = (null)}
2017-08-08 14:40:28.008 GCD[16467:291982] 2===============<NSThread: 0x60000007c340>{number = 5, name = (null)}
2017-08-08 14:40:28.009 GCD[16467:291979] 3===============<NSThread: 0x608000262100>{number = 4, name = (null)}
2017-08-08 14:40:28.009 GCD[16467:291980] 1===============<NSThread: 0x60000007c900>{number = 3, name = (null)}
2017-08-08 14:40:28.009 GCD[16467:291982] 2===============<NSThread: 0x60000007c340>{number = 5, name = (null)}

通过dispatch_group_enter(group)dispatch_group_leave(group)的配合使用来解决这个问题。

typedef void (^resultBlock) () ;

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"===============begin") ;
    dispatch_group_t group = dispatch_group_create() ;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) ;
    dispatch_group_enter(group) ;
    dispatch_group_async(group, queue, ^{
        [self testWithBlock:^{
            for(int i = 0 ; i < 4 ; i ++) {
                NSLog(@"1===============%@",[NSThread currentThread]) ;
            }
            dispatch_group_leave(group) ;
        }] ;
    }) ;
    dispatch_group_enter(group) ;
    dispatch_group_async(group, queue, ^{
        [self testWithBlock:^{
            for(int i = 0 ; i < 4 ; i ++) {
                NSLog(@"2===============%@",[NSThread currentThread]) ;
            }
            dispatch_group_leave(group) ;
        }] ;

    }) ;
    dispatch_group_enter(group) ;
    dispatch_group_async(group, queue, ^{
        [self testWithBlock:^{
            for(int i = 0 ; i < 4 ; i ++) {
                NSLog(@"3===============%@",[NSThread currentThread]) ;
            }
            dispatch_group_leave(group) ;
        }] ;
    }) ;
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"===============end") ;
    }) ;
}

- (void)testWithBlock:(resultBlock)block {
    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0*NSEC_PER_SEC)) ;
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT) ;
    dispatch_after(time, queue, ^{
        block() ;
    }) ;
}

@end

打印结果为:

2017-08-08 15:03:07.867 GCD[16548:311040] ===============begin
2017-08-08 15:03:09.868 GCD[16548:311101] 2===============<NSThread: 0x6000000773c0>{number = 5, name = (null)}
2017-08-08 15:03:09.868 GCD[16548:311098] 3===============<NSThread: 0x60000007ab40>{number = 3, name = (null)}
2017-08-08 15:03:09.868 GCD[16548:311099] 1===============<NSThread: 0x608000071d80>{number = 4, name = (null)}
2017-08-08 15:03:09.869 GCD[16548:311101] 2===============<NSThread: 0x6000000773c0>{number = 5, name = (null)}
2017-08-08 15:03:09.869 GCD[16548:311098] 3===============<NSThread: 0x60000007ab40>{number = 3, name = (null)}
2017-08-08 15:03:09.869 GCD[16548:311099] 1===============<NSThread: 0x608000071d80>{number = 4, name = (null)}
2017-08-08 15:03:09.869 GCD[16548:311101] 2===============<NSThread: 0x6000000773c0>{number = 5, name = (null)}
2017-08-08 15:03:09.869 GCD[16548:311098] 3===============<NSThread: 0x60000007ab40>{number = 3, name = (null)}
2017-08-08 15:03:09.869 GCD[16548:311099] 1===============<NSThread: 0x608000071d80>{number = 4, name = (null)}
2017-08-08 15:03:09.869 GCD[16548:311101] 2===============<NSThread: 0x6000000773c0>{number = 5, name = (null)}
2017-08-08 15:03:09.870 GCD[16548:311098] 3===============<NSThread: 0x60000007ab40>{number = 3, name = (null)}
2017-08-08 15:03:09.870 GCD[16548:311099] 1===============<NSThread: 0x608000071d80>{number = 4, name = (null)}
2017-08-08 15:03:09.870 GCD[16548:311040] ===============end

通过这种方法可以解决诸如:多个网络请求全部完成以后再进行某项操作的问题。

上一篇下一篇

猜你喜欢

热点阅读