之前使用AFN etWorking这个库来做网络请求,一直都是做的异步的,突然有需求需要改成同步的,当时从网上找了一些方法,说使用信号量来做,但是尝试了一些,都不对,最后由于时间关系,同步请求改为了系统的同步请求来实现了需求。后面仔细的去查了一下,原来信号量使用的不对,特此记录一下。

1:先看看系统自带的同步请求是如何发送的

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:BaseUrl(AppLogin)]];
//设置请求方式也POST(默认是GET)
request.timeoutInterval = 10;
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[parameters dataUsingEncoding:NSUTF8StringEncoding]];//同步方式连接服务器
NSData *responseObject = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSError *error;
if (responseObject){NSString *responseStr =  [[ NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding];NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[responseStr         dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error]  ;success(json);
}else  {failure(error);
}

2:按照网上提供的方法,自己使用信号量错误的做法,下面这段代码是写在主线程里面的。

NSString *url = @"http://dev.autocamel.com:8095/driver-0.0.1/oss/policy";
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSLog(@"1");
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[manager POST:url parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task,
id  _Nullable responseObject) {NSLog(@"%@",responseObject);NSLog(@"success");dispatch_semaphore_signal(semaphore);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {NSLog(@"fail");dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
NSLog(@"3");

分析下这段代码,创建了值为0的信号量,按照我们需要的意思,由于是异步请求,所以程序会直接运行到dispatch_semaphore_wait这个方法,由于信号量为0,并且等待时间为永久等待,所以目前不会执行NSLog(@"3"),等待信号量>0才会打印3,按照我们想的,异步请求返回后,执行回调block里面的dispatch_semaphore_signal,是信号量+1,之前会打印“success”或者“fail”,最后信号量>0,也会打印3,但实际我们看一下打印的结果,只打印了第一句NSLog("1"),为什么后面的都没有打印呢?

我们看一下AFNetWorking的源代码,我们这个请求完成后,请求结束后会执行

代理会执行下面的方法, 仔细看一下下面方法,会看到下面的所有的block默认都是在主线程执行的

应为主线程已经被信号量堵塞了,所以这个地方的成功或者是失败的回调都不可能在主线程执行,所以信号量也不可能>0,就会永远的阻塞下去,这就说明了为什么只打印了1,后面的都不会打印。

所以,修改的方法通过看源码就已经出来了,回调的block的completionGroup是没有赋值的,所以默认才会在主线程执行回调,只需要在开始的时候,给一个子线程就可以解决这个问题了

初始化的时候加上下面面一句话就可以了

执行结果如下,可以看到正确打印了我们需要的结果。

AFNetWorking改为同步请求相关推荐

  1. 如何把ajax改成同步请求,如何将Ajax请求从异步改为同步

    初学c# -- 学习笔记(四) 想想,数据库先用mysql了,这玩意小且安装方便.前面web学了些,现在学winform的.数据库先看看便捷的mysql. 下载了一个mysql5.7版的,装上居然找不 ...

  2. Servlet学习DAY_02:重定向/ 文件上传/ Cookie和Session/ 导入一个工程 / 配置欢迎页面 / 同步请求和异步请求/JSON和AJax介绍 /过滤器

    重定向 重定向是服务器告诉客户端往指定的路径再次发出请求的指令 执行过程: 当服务器执行重定向方法时会给客户端返回302状态码和一个请求路径,浏览器接收到302后会立即往指定的路径再次发出请求 res ...

  3. 实现同步请求_图解 Promise 实现原理(二)—— Promise 链式调用

    摘要 很多同学在学习 Promise 时,知其然却不知其所以然,对其中的用法理解不了.本系列文章由浅入深逐步实现 Promise,并结合流程图.实例以及动画进行演示,达到深刻理解 Promise 用法 ...

  4. ajax get 缓存 ie,Ajax异步同步请求被IE缓存的问题解决方法(get方式)

    Ajax异步同步请求被IE缓存的问题解决方法(get方式) 分类:Javascript| 发布:佚名| 查看: | 发表时间:2014/1/20 折腾了半天,程序中使用jquery的load方法进行请 ...

  5. AJAX 同步请求导致的UI阻塞问题

    遇到的一个问题,大概是这样的... 前端页面上有一个列表,遍历列表按照并发度执行ajax操作,需要等上一个并发度执行返回结果后才能决定是否进行下一个并发度的执行. 1.一开始的想法是,写一个ajax执 ...

  6. ajax同步请求后再次发送上一个请求

    场景:实现一个发送注册社团申请的功能. 实现流程:点击"注册"按钮,发送一个请求,请求路径经过解析后,由控制器里的指定的方法处理,跳转到注册页面:完成信息的编辑后,点击" ...

  7. ajax异步详解同步请求,ajax async异步请求和同步请求

    ajax async异步请求和同步请求 ajax是指异步加载.这个异步是相对于页面来说的,页面不刷新就加载服务器数据.ajax中的请求又分为同步请求和异步请求,这里是相对于进程来说的,ajax异步请求 ...

  8. 使用Ajax同步请求增加页面等待提示

    使用Ajax同步请求增加页面等待提示 最近在做项目时,有一个需求是批量打印好多个合同,使用AJAX向后台传送数据,等待后台执行后,需要把生成之后的文件地址传送过来. 后台的处理时间比较长,根据合同的多 ...

  9. ajax同步请求和异步请求

    ajax同步请求和异步请求 前序 什么是同步请求? 什么是异步请求? 比较同步和异步请求 前序 最近好长时间没写博客了,主要由于前一段时间出差,没啥心思写,今天开始重新继续.进入主题,ajax的同步请 ...

最新文章

  1. C++ 结构体struct 的使用
  2. python3中的推导式、生成器、迭代器
  3. 计算机二级考试题未来教育里占多少,计算机二级笔试试题未来教育版.doc
  4. 【错误记录】Android 可执行权限报错 ( Cannot run program “/data/user/0/cn.e/ffmpeg“: error=13,Permission denied )
  5. MYSQL:子查询关键字 ANY/SOME/IN/ALL
  6. 八年技术加持,性能提升10倍,阿里云HBase 2.0首发商用
  7. Python中操控ssh和sftp
  8. delimiter在mysql中的作用_细细研究MySql中delimiter起到的作用_MySQL
  9. java文件名命名的规则,Java文件名及其他命名规则
  10. 残差网络ResNet
  11. ORACLE 建库过程总结
  12. bash脚本:case语句
  13. Java多线程深度探索
  14. python顺序查找算法解释_顺序查找算法详解(包含C语言实现代码)
  15. cs61b实验记录(八)project 3:BearMaps 基于OSM的伯克利地图web应用
  16. Hadoop3.3.1 踩坑笔记
  17. 在项目中后端开发所需要掌握的前端知识
  18. 计算机应用一些常用技巧
  19. Python链家租房信息爬虫
  20. Miniconda安装TensorFlow并导入Pycharm

热门文章

  1. 天天在做大数据,你的时间都花在哪了
  2. mysql数据库备份和恢复
  3. pyqt5+pygame实现音乐播放器,可以自动提取文件图片,最终版本
  4. 周志华机器学习--绪论
  5. 豪掷 5 亿美元,国外支付巨头 CEO 帮助斯坦福女友实现科研自由!
  6. html中repeat的作用,repeat-y
  7. 算法练习(21):Frog Jump
  8. Sizzle选择器揭秘--Sizzle选择器
  9. eslint 换行_预计的换行符是apos;LFapos;,但在Eslint中使用gulp发现apos;CRLFapos;换行符 Dovov编程网...
  10. Python——标准库函数