iOS 异步并发多个网络请求
2018-07-11 本文已影响94人
奔跑吧小蚂蚁
在讲解域名切花之前,先说一下废话吧,域名切换名字很自然就是基础域名的切换,很多时候因为单个服务压力过大时,会在造成请求超时,或者其他的一些请求异常错误,所以需要我们进行多域名的切换操作。
多域名切换首先需要用到是多线程,这里我选用到是GCD当然也可以采用其他的方式。
同时异步并发多个网络请求,当请求完毕后,如果全部请求失败 我们给予通过,如果只有全部通过我们则选择第一个请求成公的域名地址。
当然我们有一些需要注意的点,首先我们进行域名切换时相当于多个线程同时访问同一个请求变量,多个线程同时访问一个变量时,我们知道是一定会造成这个变量的异常,所以此处我添加的一个自旋锁 ,也就时GCD中的信号量,这样可以保证每个当多个线程同时访问同一个变量时,可以让其先执行完一个,在执行下一个,但是其造作顺序依然是不固定的。也符合异步并发的要求。
另外我们在请求全部结束之后需要获取通知 ,进行提示或者UI上的变动就需要用到“ dispatch_group_t”通知相关的内容。
好了废话就到这里直接看代码吧。
- (void)asyncConcurrent{
WeakSelf
//域名数据组,从本地获取
NSArray *websiteArray = [ZFURLDefault get_websiteArray];
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
for (int i = 0; i<websiteArray.count; i++) {
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
NetworkURLString = websiteArray[i];
NSString *url = [NSString stringWithFormat:@"%@/api/v1/appversion",websiteArray[i]];
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"versionCode"] = [RWSimpleTool getCFBundleVersion];
params[@"packageName"] = [RWSimpleTool getBundleidentifier];
[ZFNetTool GET:url params:params success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) {
dispatch_group_leave(group);
ZFLog(@"\n---------------线程成功 i:%d:%@",i,url);
//isExecute默认值为NO,当第一次请求成功后赋值为YES不再调用
if (!weakSelf.isExecute) {
weakSelf.isExecute = YES;
// NetworkURLString域名基址
NetworkURLString = websiteArray[i];
}
} failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
ZFLog(@"\n---------------线程失败:%@",url);
dispatch_group_leave(group);
}];
dispatch_semaphore_signal(semaphore);
});
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
for (int i = 0; i<websiteArray.count; i++) {
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
ZFLog(@"\n---------------执行完毕可进行自己需要的操作了");
});
}
这里的网络请求改成自己写的网络请求就可以了,另外一点需要注意的是 如果没有增加自旋锁的功能,当你测试内存时你会发现会内存泄漏,因为我这边的项目是只在启动的时候调用一次,功能正常也不会崩溃,但是毕竟是一个风险,所以枷锁是必不可少的。
希望随你有用~