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);
}
复制代码
posted @ 2013-07-01 15:28  小乐"  阅读(276)  评论(0编辑  收藏  举报