GCD系列文章
本文主要总结GCD Group、Barrier和NSOperationQueue相关方法使用逻辑。
某些情况下会遇到多个任务并行处理、或任务间有依赖关系的操作。如果自己创建线程并管理线程之间资源竞争关系,比较复杂,而使用GCD或NSOperationQueue会方便快捷很多。
- 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];
}
三种方式都能实现有顺序的多任务管理
- GCD Group最适合多任务并发,等待所有任务完成后,再执行其他任务。
- GCD Barrier适合多个任务分批执行的场景,可以方便的把每一批任务隔离开,如其名栅栏。
- NSOperationQueue实现具有更高的可读性,提供取消任务、管理并发数量、线程优先级等接口。