美文网首页
iOS多线程:GCD Group、Barrier和NSOpera

iOS多线程:GCD Group、Barrier和NSOpera

作者: Pulan | 来源:发表于2018-04-02 15:56 被阅读0次

    GCD系列文章

    GCD任务和队列使用详解


    本文主要总结GCD Group、Barrier和NSOperationQueue相关方法使用逻辑。

    某些情况下会遇到多个任务并行处理、或任务间有依赖关系的操作。如果自己创建线程并管理线程之间资源竞争关系,比较复杂,而使用GCD或NSOperationQueue会方便快捷很多。

    1. GCD Group
      GCD Group主要使用场景为多个任务并发执行,在所有任务执行完成后通知。注意点是
      dispatch_group_enter(group)、dispatch_group_leave(group)成对使用,表示将任务加入
      队列和任务离开队列,dispatch_group_leave(group)要在当前任务完成后调用,
      dispatch_group_notify中的block会在加入组队列的所有任务结束后调用。
    //创建group
    dispatch_group_t group = dispatch_group_create();
    

    场景:从多个服务端接口获取数据,所有数据获取成功后,刷新UI

    使用GCD Group实现代码如下:

    - (void)testGCD_GROUP
    {
        NSLog(@"%@",NSStringFromSelector(_cmd));
        dispatch_group_t group = dispatch_group_create();
        
        dispatch_group_enter(group);
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            sleep(arc4random()%5+1);
            NSLog(@"异步从获取网络数据1");
            dispatch_group_leave(group);
        });
        
        dispatch_group_enter(group);
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            sleep(arc4random()%5+1);
            NSLog(@"异步从获取网络数据2");
            dispatch_group_leave(group);
        });
        
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
                NSLog(@"刷新UI");
        });
    }
    

    使用GCD_Barrier代码如下:

    /*
    barrier主要适用于分离多个并发任务,如并发任务(1,2,3)执行完成后执行任务4,
    任务4执行完成后执行其他任务,就可以使用dispatch_barrier将任务4加入队列,
    任务4就像栅栏一样把任务(1,2,3)和任务4之后的任务分离开。
    */
    - (void)testGCD_Barrier
    {
        NSLog(@"%@",NSStringFromSelector(_cmd));
        dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
        dispatch_async(queue, ^{
            sleep(arc4random()%5+1);
            NSLog(@"异步从获取网络数据1");
        });
        dispatch_async(queue, ^{
            sleep(arc4random()%5+1);
            NSLog(@"异步从获取网络数据2");
        });
        
        dispatch_barrier_async(queue, ^{
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"UI");
            });
        });
    }
    

    使用NSOperationQueue实现如下:

    /*
    操作队列基于GCD封装,可以替代GCD使用。
    */
    - (void)testOperation
    {
        NSLog(@"%@",NSStringFromSelector(_cmd));
        NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
            sleep(arc4random()%5+1);
            NSLog(@"任务1");
        }];
        
        NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
            sleep(arc4random()%5+1);
            NSLog(@"任务2");
        }];
        
        NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
            sleep(arc4random()%5+1);
            NSLog(@"UI");
        }];
        operation.qualityOfService = NSQualityOfServiceUserInteractive;
        //添加依赖关系:operation依赖operation1、operation2
       //添加依赖的效果就是operation会在operation1、operation2都执行完成后执行
        [operation addDependency:operation1];
        [operation addDependency:operation2];
        
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        [queue addOperations:@[operation,operation1,operation2] waitUntilFinished:NO];
    }
    

    三种方式都能实现有顺序的多任务管理

    1. GCD Group最适合多任务并发,等待所有任务完成后,再执行其他任务。
    2. GCD Barrier适合多个任务分批执行的场景,可以方便的把每一批任务隔离开,如其名栅栏。
    3. NSOperationQueue实现具有更高的可读性,提供取消任务、管理并发数量、线程优先级等接口。

    相关文章

      网友评论

          本文标题:iOS多线程:GCD Group、Barrier和NSOpera

          本文链接:https://www.haomeiwen.com/subject/oxqxhftx.html