实际开发中经常遇到需要几个网络请求全部完成过后再进行页面渲染的情况
有过多线程了解的,可能会想到一下几种方式:
1.采用NSOperation的子类NSInvocationOperation、NSBlockOperation,添加依赖;
//创建NSInvocationOperation对象
NSInvocationOperation *operation1=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test1) object:nil];
NSInvocationOperation *operation2=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test2) object:nil];
//添加依赖,先执行1--->再执行2
[operation2 addDependency:operation1];
//创建NSOperationQueue
NSOperationQueue * queue=[[NSOperationQueue alloc]init];
//把操作添加到队列中
[queue addOperation:operation1];
[queue addOperation:operation2];
2.使用dispatch group,当group中方法全部执行完成后回到主队列中传值
//创建group
dispatch_group_t group = dispatch_group_create();
//全局并发队列中添加第一个方法
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i=0; i<1000; i++) {
NSLog(@"%@ == %d",[NSThread currentThread],i);
}
});
//全局并发队列中添加第二个方法
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i=0; i<1000; i++) {
NSLog(@"%@ == %d",[NSThread currentThread],i);
}
});
//队列组中全部执行完成执行
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"全部执行完成");
});
发送的异步请求,当这个异步请求发送过后,就已经算这个方法执行完成。使用上述方法无法达到我们想要的效果。
3.dispatch_group_enter(<#dispatch_group_t group#>) 与dispatch_group_leave(<#dispatch_group_t group#>)搭配使用
//创建一个线程组
dispatch_group_t group = dispatch_group_create();
//存储错误信息
__block NSMutableArray *errorArr = [NSMutableArray new];
//存储返回回来的数据
__block NSArray *arr1 = [NSArray new];
__block NSArray *arr2 = [NSArray new];
__block NSArray *arr3 = [NSArray new];
//调用单独封装子网络请求方法(AFNetworking)在数据返回传值的block中leave
dispatch_group_enter(group);
[self XXXXXXXXXXXXXXXXXXXXXX1 complete:^(id data) {
//Do Something
dispatch_group_leave(group);
}];
dispatch_group_enter(group);
[self XXXXXXXXXXXXXXXXXXXXXX2 complete:^(id data) {
//Do Something
dispatch_group_leave(group);
}];
dispatch_group_enter(group);
[self XXXXXXXXXXXXXXXXXXXXXX3 complete:^(id data) {
//Do Something
dispatch_group_leave(group);
}];
#pragma mark - 完成全部数据请求回到主线程中传递数据并刷新UI
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"完成全部数据请求");
//如果有错误信息则数据请求失败
if (errorArr && errorArr.count>0) {
handle(@{@"result":@"0",@"error":@"请求数据失败"});
}else{
//Do Something
}
});
使用这种方法就能达到我们想要的效果,一个enter 必须对应一个leave,成对出现!