详解iOS中多个网络请求的同步问题总结

发布时间 - 2026-01-11 00:56:57    点击率:

场景描述:我们同时发出了a、b、c 3个网络请求,我们希望在a、b、c 3个网络请求都结束的时候获得一个通知。

常见解决方法:通过度娘目前找到两种做法;1、通过添加标识来判断请求是否全部结束 2、dispatch_group + 信号量

本篇文章demo

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  # 多个网络请求同步  # 网络请求同步任务  # ios同步网络请求数据  # iOS判断网络请求超时的方法  # iOS中多网络请求的线程安全详解  # iOS当多个网络请求完成后执行下一步的方法详解  # 回调  # 信号量  # 的是  # 第一个  # 第二个  # 解决方法  # 是在  # 很好  # 放在  # 两种  # 遍历  # 这个问题  # 批处理  # 大大的  # 多说  # 来实现  # 塞进  # 开源  # 大家多多  # 有一个 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何用腾讯建站主机快速创建免费网站?  如何在香港服务器上快速搭建免备案网站?  如何获取PHP WAP自助建站系统源码?  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  Python文件操作最佳实践_稳定性说明【指导】  Laravel如何使用Laravel Vite编译前端_Laravel10以上版本前端静态资源管理【教程】  Laravel如何构建RESTful API_Laravel标准化API接口开发指南  js代码实现下拉菜单【推荐】  Laravel如何使用Gate和Policy进行授权?(权限控制)  Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法  Laravel如何清理系统缓存命令_Laravel清除路由配置及视图缓存的方法【总结】  小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像  简历没回改:利用AI润色让你的文字更专业  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  Firefox Developer Edition开发者版本入口  Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试  香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧  厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?  米侠浏览器网页图片不显示怎么办 米侠图片加载修复  动图在线制作网站有哪些,滑动动图图集怎么做?  BootStrap整体框架之基础布局组件  如何用PHP快速搭建高效网站?分步指南  图册素材网站设计制作软件,图册的导出方式有几种?  Claude怎样写约束型提示词_Claude约束提示词写法【教程】  javascript中对象的定义、使用以及对象和原型链操作小结  ,怎么在广州志愿者网站注册?  Laravel如何使用Service Provider服务提供者_Laravel依赖注入与容器绑定【深度】  Android自定义listview布局实现上拉加载下拉刷新功能  微信小程序 HTTPS报错整理常见问题及解决方案  微信小程序 scroll-view组件实现列表页实例代码  如何快速完成中国万网建站详细流程?  什么是JavaScript解构赋值_解构赋值有哪些实用技巧  Laravel如何为API生成Swagger或OpenAPI文档  如何注册花生壳免费域名并搭建个人网站?  如何快速搭建二级域名独立网站?  大连网站制作公司哪家好一点,大连买房网站哪个好?  百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏  高端建站如何打造兼具美学与转化的品牌官网?  laravel怎么配置和使用PHP-FPM来优化性能_laravel PHP-FPM配置与性能优化方法  Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例  WordPress 子目录安装中正确处理脚本路径的完整指南  Win11关机界面怎么改_Win11自定义关机画面设置【工具】  网站制作免费,什么网站能看正片电影?  原生JS获取元素集合的子元素宽度实例  Laravel怎么判断请求类型_Laravel Request isMethod用法  Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康  如何在新浪SAE免费搭建个人博客?  Windows Hello人脸识别突然无法使用  Linux网络带宽限制_tc配置实践解析【教程】  nginx修改上传文件大小限制的方法