GCD检测多个异步任务完成

当我们需要在多个异步的任务完成之后去处理某些事情,如异步下载多张图片,等所有图片下载完成之后,再去做一些事情,那么怎样检测这些异步下载完所有图片的事件队列呢?可以用dispatch_group,她可以在添加到它里面的所有任务都完成之后同步(阻塞主线程)异步的通知,以便做接下来的事情

用dispatch_group_wait同步通知

一般的用法是: 在 某一个异步下载任务之前调用dispatch_group_enter(dispatch_group)进入diapatch_group

在改异步下载任务完成之后调用dispatch_group_leave(dispatch_group)来退出

以上重复的执行,直到所有的任务执行完毕

然后

dispatch_group_wait(dispatch_group, DISPATCH_TIME_FOREVER); // 5

这行代码之后的代码会在所有的任务完成之后执行,他有个返回值,如果超时会返回一个非零值

- (void)downloadPhotosWithCompletionBlock:(BatchPhotoDownloadingCompletionBlock)completionBlock

{

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1

__block NSError *error;

dispatch_group_t downloadGroup = dispatch_group_create(); // 2

for (NSInteger i = 0; i < 3; i++) {

NSURL *url;

switch (i) {

case 0:

url = [NSURL URLWithString:kOverlyAttachedGirlfriendURLString];

break;

case 1:

url = [NSURL URLWithString:kSuccessKidURLString];

break;

case 2:

url = [NSURL URLWithString:kLotsOfFacesURLString];

break;

default:

break;

}

dispatch_group_enter(downloadGroup); // 3

Photo *photo = [[Photo alloc] initwithURL:url

withCompletionBlock:^(UIImage *image, NSError *_error) {

if (_error) {

error = _error;

}

dispatch_group_leave(downloadGroup); // 4

}];

[[PhotoManager sharedManager] addPhoto:photo];

}

dispatch_group_wait(downloadGroup, DISPATCH_TIME_FOREVER); // 5

dispatch_async(dispatch_get_main_queue(), ^{ // 6

if (completionBlock) { // 7

completionBlock(error);

}

});

});

}

参考博文:http://ios.jobbole.com/81566/

第二种异步通知:用dispatch_group_notify,当dispatch_group中没有任何任务时就会调用该方法

用一下代码替换掉dispatch_group_wait()及之后的代码


dispatch_group_notify(downloadGroup, dispatch_get_main_queue(), ^{ // 4

if (completionBlock) {

completionBlock(error);

}

});

上面在下载图片时迭代了三次,依次下载图片,这样效率不是很高,可以改进一下,让for循环并发的执行,dispatch_apply就是做这个的,他表现的像个for循环,但可以并发的迭代,并且是同步的,在所有的迭代完成以后才返回

你可能感兴趣的:(GCD检测多个异步任务完成)