GCD-2
正在学习这块的东西 转载两篇好文章 原文地址http://www.cnblogs.com/carlton/archive/2013/06/25/3155239.html
上一篇讲了一下GCD的基本用法,这一篇稍微升华一下,说说关于GCD编程中‘同步’的那些事儿。
先看一下原型:
-(void) asyncMethodForPrint:(NSString *) ch{ NSLog(@"asyncMethodForPrint[%@]", ch); } -(void) test { NSArray *arr = [NSArray arrayWithObjects:@"a",@"b",@"c",@"d",@"e",@"f",@"g",nil]; for (NSString *item in arr) { [self asyncMethodForPrint:item]; } }
显然上面是按a~g的顺序进行日志输出,那么对于一个多核移动设备,充分利用起咱们的cpu的一种形式是什么呢?当然是用GCD来弄了,通过GCD,通常系统自己维护一个work线程池,当有task需要被执行的时候,从线程池中‘拿’一个出来直接就能用,因此上面的代码,在GCD编程的方式下,并发执行的形式为:
-(void) asyncMethodForPrint:(NSString *) ch{ NSLog(@"asyncMethodForPrint[%@]", ch); } -(void) test { NSArray *arr = [NSArray arrayWithObjects:@"a",@"b",@"c",@"d",@"e",@"f",@"g",nil]; for (NSString *item in arr) { dispatch_async(dispatch_get_global_queue(0, 0ul), ^{ [self asyncMethodForPrint:item]; }); } }
很简单,至此,我们还是稍稍重复了上一篇所讲的内容,当然,日志不会再按顺序输出了,而是:
2013-06-25 18:23:47.171 GCDExample[4318:1303] asyncMethodForPrint[a] 2013-06-25 18:23:47.171 GCDExample[4318:3d07] asyncMethodForPrint[d] 2013-06-25 18:23:47.175 GCDExample[4318:1303] asyncMethodForPrint[e] 2013-06-25 18:23:47.175 GCDExample[4318:3d07] asyncMethodForPrint[f] 2013-06-25 18:23:47.171 GCDExample[4318:1e03] asyncMethodForPrint[c] 2013-06-25 18:23:47.171 GCDExample[4318:1c03] asyncMethodForPrint[b] 2013-06-25 18:23:47.176 GCDExample[4318:1303] asyncMethodForPrint[g]
关于wait
那么,现在问题来了,我们目前的任务仅仅是print一个个独立无关联的字符串,当然可以通过concurrent队列走并发的形式了,但如果业务变了,俺们需要在for循环后面打印asyncMethodForPrint方法执行的次数:
static int counter = 0; -(void) asyncMethodForPrint:(NSString *) ch{ NSLog(@"asyncMethodForPrint[%@]", ch); counter++; } -(void) test { NSArray *arr = [NSArray arrayWithObjects:@"a",@"b",@"c",@"d",@"e",@"f",@"g",nil]; for (NSString *item in arr) { dispatch_async(dispatch_get_global_queue(0, 0ul), ^{ [self asyncMethodForPrint:item]; }); } NSLog(@"count: %d", counter); }
悲剧了,count打印的结果不是0,就是1 ,因为dispatch_async会立即返回。如何解决这个问题,思路是:输出count之前,等待前面所有的task完结。那么需要引入group的概念,
修改后代码为:
static int counter = 0; -(void) asyncMethodForPrint:(NSString *) ch{ NSLog(@"asyncMethodForPrint[%@]", ch); counter++; } -(void) test { NSArray *arr = [NSArray arrayWithObjects:@"a",@"b",@"c",@"d",@"e",@"f",@"g",nil]; // 创建一个group dispatch_group_t group_1 = dispatch_group_create(); for (NSString *item in arr) { // 将需要聚集执行的task作为group形式执行 dispatch_group_async(group_1, dispatch_get_global_queue(0, 0ul), ^{ [self asyncMethodForPrint:item]; }); } dispatch_group_wait(group_1, DISPATCH_TIME_FOREVER); dispatch_release(group_1); // 上面两句也可以写成: // dispatch_group_notify(group_1, dispatch_get_global_queue(0, 0ul), ^{ // NSLog(@"count: %d", counter); // }); // 这样牛逼之处在于它还能异步执行。。。尽管这个语句看来意义不大 NSLog(@"count: %d", counter); }