假如有一组任务,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"]; });
原文:http://www.cnblogs.com/rayshen/p/4911131.html