异步执行几个耗时操作,当这几个操作都完成之后再回到主线程进行操作,就可以用到队列组了。
队列组有下面几个特点:
- 所有的任务会并发的执行(不按序)。
- 所有的异步函数都添加到队列中,然后再纳入队列组的监听范围。
- 使用dispatch_group_notify函数,来监听上面的任务是否完成,如果完成, 就会调用这个方法。
dispatch_group的关键函数如下:
-
dispatch_group_t
队列组对象类 -
dispatch_group_async
先把任务放到队列中,然后再讲队列放入队列组 -
dispatch_group_notify
用于获取执行完毕回调 -
dispatch_wait
回到当前线程继续执行后面的操作(会阻塞当前线程) -
dispatch_group_enter
用于标志一个任务追加到group,执行一次,相当于- - group中未执行完毕任务数+1 -
dispatch_group_leave
用于标志一个任务离开了group,执行一次,相当于- group中未执行完毕任务数-1
题1:
有n个请求(耗时操作)分别异步执行,当这些请求全部执行完了回主线程刷新UI。
队列组示例代码:
- (void)testGroup {
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
NSLog(@"队列组:有一个耗时操作完成!");
});
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
NSLog(@"队列组:有一个耗时操作完成!");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"队列组:前面的耗时操作都完成了,回到主线程进行相关操作");
});
}
打印结果如下:
队列组:有一个耗时操作完成!
队列组:有一个耗时操作完成!
队列组:前面的耗时操作都完成了,回到主线程进行相关操作
- (void)downloadImages {
NSString *fileDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
// stringByAppendingPathComponent:@"image"];
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
_imgGroup = dispatch_group_create();
NSLog(@"start downloading");
//图1
dispatch_group_async(_imgGroup, globalQueue, ^{
dispatch_group_enter(_imgGroup);
NSString *filePath = [fileDir stringByAppendingPathComponent:@"image0.jpg"];
[self downloadImageToPath:filePath url:self.imgURLs[0]];
});
//图2
dispatch_group_async(_imgGroup, globalQueue, ^{
dispatch_group_enter(_imgGroup);
NSString *filePath = [fileDir stringByAppendingPathComponent:@"image1.jpg"];
[self downloadImageToPath:filePath url:self.imgURLs[1]];
});
//图3
dispatch_group_async(_imgGroup, globalQueue, ^{
dispatch_group_enter(_imgGroup);
NSString *filePath = [fileDir stringByAppendingPathComponent:@"image2.jpg"];
[self downloadImageToPath:filePath url:self.imgURLs[2]];
});
//下载完成会调`dispatch_group_notify`通知刷新
dispatch_group_notify(_imgGroup, globalQueue, ^{
NSLog(@"finish download");
});
}
- (void)downloadImageToPath:(NSString *)filePath url:(NSString *)url{
AFURLSessionManager *sessionMgr = [[AFURLSessionManager alloc] initWithSessionConfiguration:self.sessionConfig];
NSURL *imgURL = [NSURL URLWithString:url];
NSURLRequest *request = [NSURLRequest requestWithURL:imgURL];
NSURLSessionDownloadTask *downloadTask =
[sessionMgr downloadTaskWithRequest:request
progress:nil
destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
NSURL *documentURL = [NSURL fileURLWithPath:filePath];
return documentURL;
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
dispatch_group_leave(_imgGroup);
}];
[downloadTask resume];
}
网友评论