这篇文章主要为大家展示了“iOS中如何实现多个网络请求的同步”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“iOS中如何实现多个网络请求的同步”这篇文章吧。
场景描述:我们同时发出了a、b、c 3个网络请求,我们希望在a、b、c 3个网络请求都结束的时候获得一个通知。
常见解决方法:通过度娘目前找到两种做法;1、通过添加标识来判断请求是否全部结束 2、dispatch_group + 信号量
1、添加标识的解决方法
在遇到这个问题时首先想到了唐巧大大的猿题库团队开源的网络框架YTKNetwork,然后阅读源码发现YTKNetwork是通过添加标识来实现网络请求的批量请求处理;
话不多说直接上代码在YTKNetwork里负责进行网络批处理请求的是YTKBatchRequest类,下面看下它的使用示例:
YTKBatchRequest *batchRequest = [[YTKBatchRequest alloc] initWithRequestArray:@[a, b, c, d]];
先调用初始化方法把4个网络请求的实例塞进去,看下这个初始化方法
- (id)initWithRequestArray:(NSArray )requestArray { self = [super init]; if (self) { _requestArray = [requestArray copy]; _finishedCount = 0; for (YTKRequest req in _requestArray) { if (![req isKindOfClass:[YTKRequest class]]) { YTKLog(@"Error, request item must be YTKRequest instance."); return nil; } } } return self; }
我们看到有一个_finishedCount的变量根据字面很好理解是用来记录请求完成的个数,然后我们全局搜下这个变量,发现只有在下面的这个方法中用到了这个变量
- (void)requestFinished:(YTKRequest *)request { _finishedCount++; if (_finishedCount == _requestArray.count) { [self toggleAccessoriesWillStopCallBack]; if ([_delegate respondsToSelector:@selector(batchRequestFinished:)]) { [_delegate batchRequestFinished:self]; } if (_successCompletionBlock) { _successCompletionBlock(self); } [self clearCompletionBlock]; [self toggleAccessoriesDidStopCallBack]; [[YTKBatchRequestAgent sharedInstance] removeBatchRequest:self]; } }
上述方法是网络请求结束的回调代理方法,完成后_finishedCount计数加1,然后和保存网络请求实例的数组元素个数进行比较如果相等说明所有的请求都已经完成,调用回调的代理方法及block请求结束。
然后YTKNetwork对于批量网络请求失败的处理是,只要一个失败就立即停止请求,调用失败回调:
- (void)requestFailed:(YTKRequest )request { [self toggleAccessoriesWillStopCallBack]; // Stop for (YTKRequest req in _requestArray) {//遍历请求实例数组 [req stop];//停止请求 } // Callback //回调 if ([_delegate respondsToSelector:@selector(batchRequestFailed:)]) { [_delegate batchRequestFailed:self]; } if (_failureCompletionBlock) { _failureCompletionBlock(self); } // Clear [self clearCompletionBlock]; [self toggleAccessoriesDidStopCallBack]; [[YTKBatchRequestAgent sharedInstance] removeBatchRequest:self]; }
总结:YTKNetwork的做法大致就是用一个变量记录完成请求的个数,然后在单个网络请求结束回调的时候判断当前完成的网络请求个数是否和总的网络请求个数相等,如果相等则说明请求结束。
2、dispatch_group + 信号量
参考文章采用的是group + 信号量,下面示例采用dispatch_group_enter、dispatch_group_leave实现详见 本篇文章demo。
- (void)loadRequest1 { dispatch_group_t dispatchGroup = dispatch_group_create(); dispatch_group_enter(dispatchGroup); [MALAFNManger getDataWithUrl:Url1 parameters:nil finish:^(RequestResult result) { NSLog(@"第一个请求完成"); dispatch_group_leave(dispatchGroup); } des:@"第一个url"]; dispatch_group_enter(dispatchGroup); [MALAFNManger getDataWithUrl:Url2 parameters:nil finish:^(RequestResult result) { dispatch_async(dispatch_get_global_queue(0, 0), ^{ sleep(10);//网络请求结束后回调是在主线程如果sleep放在外面会阻塞主线程 NSLog(@"第二个请求完成"); dispatch_group_leave(dispatchGroup); }); } des:@"第二个url"]; dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){ NSLog(@"请求完成"); }); }
以上是“iOS中如何实现多个网络请求的同步”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。