iOS多线程:GCD Group、Barrier和NSOpera

2018-04-02  本文已影响0人  Pulan

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实现具有更高的可读性,提供取消任务、管理并发数量、线程优先级等接口。
上一篇下一篇

猜你喜欢

热点阅读