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"];
        });
  • 相关阅读:
    Linux磁盘与文件系统操作命令
    Linux 进程管理命令
    文件备份与压缩命令
    Linux系统命令
    CentOS6和CentOS7的区别
    nginx安装配置
    docker的容器和镜像的清理
    Zabbix-Agent配置文件详解
    k8s 获取登录token命令
    vmware 端口转发设置
  • 原文地址:https://www.cnblogs.com/rayshen/p/4911131.html
Copyright © 2011-2022 走看看