1、2个请求没有依赖性,可是要求2个请求都完成后才能刷新UI。ios
2、2个请求有依赖性,A请求完成后,B请求须要用到 A 返回的结果 做为参数进行请求。api
先解决第一个:网络
使用GCD的 group ,等两个请求都完成后,在刷新UI.代码以下:异步
- (void)request{ //建立一个GCD group self.group = dispatch_group_create(); //将请求放入group中处理 dispatch_group_async(self.group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self request1]; }); dispatch_group_async(self.group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self request2]; }); dispatch_group_async(self.group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self request3]; }); //监听group中任务是否都完成了,完成了就执行刷新界面 dispatch_group_notify(self.group, dispatch_get_main_queue(), ^{ NSLog(@"刷新界面"); }); }
//请求1 -(void)request1{ AFHTTPSessionManager *manger = [AFHTTPSessionManager manager]; NSString *url = @"http://v3.wufazhuce.com:8000/api/channel/movie/more/0?platform=ios&version=v4.0.1"; [manger GET:url parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSArray *data = responseObject[@"data"]; for (NSDictionary *dic in data) { NSLog(@"请求1---%@",dic[@"id"]); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { }]; } //请求2 -(void)request2{ AFHTTPSessionManager *manger = [AFHTTPSessionManager manager]; NSString *url = @"http://v3.wufazhuce.com:8000/api/channel/movie/more/0?platform=ios&version=v4.0.1"; [manger GET:url parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSArray *data = responseObject[@"data"]; for (NSDictionary *dic in data) { NSLog(@"请求2---%@",dic[@"id"]); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { }]; } //请求3 -(void)request3{ AFHTTPSessionManager *manger = [AFHTTPSessionManager manager]; NSString *url = @"http://v3.wufazhuce.com:8000/api/channel/movie/more/0?platform=ios&version=v4.0.1"; [manger GET:url parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSArray *data = responseObject[@"data"]; for (NSDictionary *dic in data) { NSLog(@"请求3---%@",dic[@"id"]); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { }]; }
运行结果:async
我擦,说好的先执行group中的任务,等group中的任务都执行完成后,再执行刷新UI的呢?事与愿违啊!url
通过查证找出了缘由,缘由就是:咱们的网络请求AFN发送请求也是在异步线程的。上面这种将请求放入group的写法遵照的整组所有执行完毕指的是三个block写的代码直观进行执行完,就算执行完毕。也就是说[self request1] 执行AFN的代码完了,不包含AFN异步请求。 所以会出现这样的结果。spa
改正:线程
网上有不少人用group 和 信号量来解决这个问题,其实不须要信号量,队列组就能解决了。只要换一种方式将任务加入队列组就好了。code
- (void)request{ self.group = dispatch_group_create(); //下面的任务立刻要放到group中执行了 dispatch_group_enter(self.group); [self request1]; //下面的任务立刻要放到group中执行了 dispatch_group_enter(self.group); [self request2]; //下面的任务立刻要放到group中执行了 dispatch_group_enter(self.group); [self request3]; dispatch_group_notify(self.group, dispatch_get_main_queue(), ^{ NSLog(@"刷新界面"); }); }
-(void)request1{ AFHTTPSessionManager *manger = [AFHTTPSessionManager manager]; NSString *url = @"http://v3.wufazhuce.com:8000/api/channel/movie/more/0?platform=ios&version=v4.0.1"; [manger GET:url parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSArray *data = responseObject[@"data"]; for (NSDictionary *dic in data) { NSLog(@"请求1---%@",dic[@"id"]); } //任务完成了,该任务从group中移除 dispatch_group_leave(self.group); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { //任务完成了,该任务从group中移除 dispatch_group_leave(self.group); }]; } -(void)request2{ AFHTTPSessionManager *manger = [AFHTTPSessionManager manager]; NSString *url = @"http://v3.wufazhuce.com:8000/api/channel/movie/more/0?platform=ios&version=v4.0.1"; [manger GET:url parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSArray *data = responseObject[@"data"]; for (NSDictionary *dic in data) { NSLog(@"请求2---%@",dic[@"id"]); } //任务完成了,该任务从group中移除 dispatch_group_leave(self.group); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { //任务完成了,该任务从group中移除 dispatch_group_leave(self.group); }]; } -(void)request3{ AFHTTPSessionManager *manger = [AFHTTPSessionManager manager]; NSString *url = @"http://v3.wufazhuce.com:8000/api/channel/movie/more/0?platform=ios&version=v4.0.1"; [manger GET:url parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSArray *data = responseObject[@"data"]; for (NSDictionary *dic in data) { NSLog(@"请求3---%@",dic[@"id"]); } //任务完成了,该任务从group中移除 dispatch_group_leave(self.group); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { //任务完成了,该任务从group中移除 dispatch_group_leave(self.group); }]; }
这种dispatch_group_enter和dispatch_group_leave是成对出现的,当进入一个操做后,在适当的位置加上dispatch_group_leave,好比在这里,进入第一个 enter 执行 request1 操做,那么在这个方法中异步返回的时候(成功或失败)写上 dispatch_gropu_leave,这样就包含了异步的状况。orm
2、解决有依赖的两个请求
// 建立一个队列 NSOperationQueue *queue = [[NSOperationQueue alloc]init]; // 建立一个A操做 NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{ [self requestA]; }]; // 建立一个B操做 NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{ [self requestB]; }]; //添加依赖 B要在A打印完在进行打印 因此是B依赖于A 那么只须要添加以下代码便可完成 [operationB addDependency:operationA]; // 分别加入到队列中 [queue addOperation:operationA]; [queue addOperation:operationB];
-(void)requestA{ AFHTTPSessionManager *manger = [AFHTTPSessionManager manager]; NSString *url = @"http://v3.wufazhuce.com:8000/api/channel/movie/more/0?platform=ios&version=v4.0.1"; [manger GET:url parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSArray *data = responseObject[@"data"]; for (NSDictionary *dic in data) { NSLog(@"请求AAA---%@",dic[@"id"]); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { }]; } -(void)requestB{ AFHTTPSessionManager *manger = [AFHTTPSessionManager manager]; NSString *url = @"http://v3.wufazhuce.com:8000/api/channel/movie/more/0?platform=ios&version=v4.0.1"; [manger GET:url parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSArray *data = responseObject[@"data"]; for (NSDictionary *dic in data) { NSLog(@"请求BBB---%@",dic[@"id"]); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { }]; }
这里我没有在一个线程请求返回成功后,再发起第二个请求,这种方式也能解决问题,可是这样写代码会比较乱,我不喜欢这么写。