两种方式
1,队列组 dispatch_group_async
dispatch_group_async是用于同步工作的,但是,它的判断标准是放入的block是否执行完毕,如果我们放入block中包含异步的网络请求,这个方法无法在网络数据返回后再进行同步,计数器方式可以解决这个问题。
2,计数器dispatch_group_enter和dispatch_group_leave
原理:维护一个计数器,当计数器和网络请求数相等时,调用最后的处理
就是dispatch_group_enter会对group的内部计数加一,dispatch_group_leave会对group的内部计数减一,就类似以前的retain和release方法。说白了也是维护了一个计数器。
dispatch_group_enter、dispatch_group_leave
dispatch_group_enter 标志着一个任务追加到 group,执行一次,相当于 group 中未执行完毕任务数+1
dispatch_group_leave 标志着一个任务离开了 group,执行一次,相当于 group 中未执行完毕任务数-1。
当 group 中未执行完毕任务数为0的时候,才会使dispatch_group_wait解除阻塞,以及执行追加到dispatch_group_notify中的任务。
伪代码:
创建dispatch_group_t dispatchGroup = dispatch_group_create();
异步之前执行dispatch_group_enter(dispatchGroup);
异步执行完毕后执行 dispatch_group_leave(dispatchGroup);
所有异步执行之后执行
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
NSLog(@"end");
});
演示代码
-(void)loadGroup2{
NSURLSession *session = [NSURLSession sharedSession];
dispatch_group_t dispatchGroup = dispatch_group_create();
dispatch_group_enter(dispatchGroup);
NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
sleep(2.0);
NSLog(@"got2 data from internet2");
dispatch_group_leave(dispatchGroup);
}];
// 执行网络任务
[task resume];
dispatch_group_enter(dispatchGroup);
NSURLSessionDataTask *task2 = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
sleep(2.0);
NSLog(@"got2 data from internet1");
dispatch_group_leave(dispatchGroup);
}];
[task2 resume];
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
NSLog(@"end");
});
}
-(void)loadGroup{
NSURLSession *session = [NSURLSession sharedSession];
dispatch_queue_t dispatchQueue = dispatch_queue_create("test.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t dispatchGroup = dispatch_group_create();
dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
sleep(2.0);
NSLog(@"got1 data from internet2");
}];
// 执行网络任务
[task resume];
});
dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
dispatch_group_enter(dispatchGroup);
NSURLSessionDataTask *task2 = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
sleep(2.0);
NSLog(@"got1 data from internet1");
}];
[task2 resume];
});
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
NSLog(@"end");
});
}
网友评论