请选择 进入手机版 | 继续访问电脑版
0 1326

AFNetworking拆解分析(11)

admin 于 2017-1-18 15:49 发表 [复制链接]
现在我们回到一开始初始化的这行代码上:
[Objective-C] 纯文本查看 复制代码
self.operationQueue.maxConcurrentOperationCount = 1;

1)首先我们要明确一个概念,这里的并发数仅仅是回调代理的线程并发数。而不是请求网络的线程并发数。请求网络是由NSUrlSession来做的,它内部维护了一个线程池,用来做网络请求。它调度线程,基于底层的CFSocket去发送请求和接收数据。这些线程是并发的。
2)明确了这个概念之后,我们来梳理一下AF3.x的整个流程和线程的关系:
  • 我们一开始初始化sessionManager的时候,一般都是在主线程,(当然不排除有些人喜欢在分线程初始化...)
  • 然后我们调用get或者post等去请求数据,接着会进行request拼接,AF代理的字典映射,progress的KVO添加等等,到NSUrlSession的resume之前这些准备工作,仍旧是在主线程中的。
  • 然后我们调用NSUrlSession的resume,接着就跑到NSUrlSession内部去对网络进行数据请求了,在它内部是多线程并发的去请求数据的。
  • 紧接着数据请求完成后,回调回来在我们一开始生成的并发数为1的NSOperationQueue中,这个时候会是多线程串行的回调回来的。(注:不明白的朋友可以看看雷纯峰大神这篇iOS 并发编程之 Operation Queues
  • 然后我们到返回数据解析那一块,我们自己又创建了并发的多线程,去对这些数据进行了各种类型的解析。
  • 最后我们如果有自定义的completionQueue,则在自定义的queue中回调回来,也就是分线程回调回来,否则就是主队列,主线程中回调结束。
3)最后我们来解释解释为什么回调Queue要设置并发数为1:
  • 我认为AF这么做有以下两点原因:
    1)众所周知,AF2.x所有的回调是在一条线程,这条线程是AF的常驻线程,而这一条线程正是AF调度request的思想精髓所在,所以第一个目的就是为了和之前版本保持一致。
    2)因为跟代理相关的一些操作AF都使用了NSLock。所以就算Queue的并发数设置为n,因为多线程回调,锁的等待,导致所提升的程序速度也并不明显。反而多task回调导致的多线程并发,平白浪费了部分性能。
    而设置Queue的并发数为1,(注:这里虽然回调Queue的并发数为1,仍然会有不止一条线程,但是因为是串行回调,所以同一时间,只会有一条线程在操作AFUrlSessionManager的那些方法。)至少回调的事件,是不需要多线程并发的。回调没有了NSLock的等待时间,所以对时间并没有多大的影响。(注:但是还是会有多线程的操作的,因为设置刚开始调起请求的时候,是在主线程的,而回调则是串行分线程。)
当然这仅仅是我个人的看法,如果有不同意见的欢迎交流~
至此我们AF3.X业务层的逻辑,基本上结束了。小伙伴们,看到这你明白了AF做了什么了吗?可能很多朋友要扔鸡蛋了...可能你还是没觉得AF到底有什么用,我用NSUrlSession不也一样,我干嘛要用AF,在这里,我暂时卖个关子,等我们下篇讲完AFSecurityPolicy和部分UIKit的扩展,以及AF2.x的核心类源码实现之后,我们再好好总结。
文 /涂耀辉(简书作者)
原文链接:http://www.jianshu.com/p/f32bd79233da

举报 使用道具
| 回复

共 0 个关于本帖的回复 最后回复于 2017-1-18 15:49

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

本文内容不够精彩,我要自己发布

发布新帖

推荐阅读

    拥有的,不仅是技术!还有...
    联系 Email: support.36ji@qq.com

    • 关注酷站官方微博
      了解最新动态

    • 关注酷站微信公众号
      这里有好玩的讯息

    • 加入酷站交流群
      不断在这里成长

    © 2014-2017 36ji网络科技有限公司 . All rights reserved.
    京ICP备14001609号

    Archiver|    
    Powered by Discuz! X3.2 © 2001-2013 Comsenz Inc.
    快速回复 返回顶部 返回列表