zoukankan      html  css  js  c++  java
  • iOS GCD中的dispatch_group

    假如有一组任务,A,B,C,D,其中ABC是可以并行的,D是必须在ABC任务完成后再执行的。

    (举个场景,比如吃饭前必须先做菜、做饭和买饮料,然后才能开吃)

    1.关于ABC的并行:

        采用多线程的方式就能实现。比如NSThread,NSOperation或是GCD.

    2.然后关于ABC完成再执行D:

    A方法:

          这可以采用操作系统里临界资源的概念:

          设立一个标志位flag,其值为任务数量,每个任务执行后flag--,并且每次任务的执行都要判断flag,为0时执行D。

    B方法:

           然而在GCD中有一个接口可以直接完成类似操作,就是GCD_Group,其中的重点就是把各个Queue加到Group里,然后

     dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

    具体的操作方式如下:

    -(void)GCDTask{
        NSArray *array =@[@"TaskA",@"TaskB",@"TaskC"];
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_group_t group = dispatch_group_create();
        for(id obj in array)
            dispatch_group_async(group, queue, ^{
                [self doSomethingIntensiveWith:obj];
            });
        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
        [self doSomethingIntensiveWith:@"TaskD"];
    
    }
    
    -(void)doSomethingIntensiveWith:(NSString *)str{
        NSLog(@"%@",str);
    }

    dispatch_group_wait()函数会一直等到前面Group中的内容执行完再执行下面内容,但因此也会产生阻塞线程的问题,可以考虑使用另一个函数:

    //等group里的task都执行完后执行notify方法里的内容
        dispatch_group_notify(group, queue, ^{
            [self doSomethingIntensiveWith:@"TaskD"];
        });

    具体如下:

    -(void)GCDTask{
        NSArray *array =@[@"TaskA",@"TaskB",@"TaskC"];
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_group_t group = dispatch_group_create();
        for(id obj in array)
            dispatch_group_async(group, queue, ^{
                [self doSomethingIntensiveWith:obj];
            });
        //等group里的task都执行完后执行notify方法里的内容
        dispatch_group_notify(group, queue, ^{
            [self doSomethingIntensiveWith:@"TaskD"];
        });
        [self doSomethingIntensiveWith:@"TaskE"];
    }
    
    -(void)doSomethingIntensiveWith:(NSString *)str{
        NSLog(@"%@",str);
    }

     这样就不会应该线程阻塞了。

    另外,如果需要在Notify里回到主线程进行UI操作,可以修改成:

        //等group里的task都执行完后执行notify方法里的内容
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            //..do something with UI
            [self doSomethingIntensiveWith:@"TaskD"];
        });
  • 相关阅读:
    easyUI的汇总列,在前端生成
    return返回两个三元表达式的和,返回不正确,同样要注意在JavaScript中,也是如此
    清除浮动有哪些方式?比较好的方式是哪一种?
    浏览器重置样式
    MUI框架的缩写输入
    会自动消失的提示信息
    JSON.stringify转化报错
    Jquery on方法绑定事件后执行多次
    属性索引选择元素
    字符串赋值数字时的问题
  • 原文地址:https://www.cnblogs.com/rayshen/p/4911131.html
Copyright © 2011-2022 走看看