AF3.x是基于NSURLSession来封装的 ASI CFNetwork框架
AF分为如下5个功能模块:
网络通信模块(AFURLSessionManager、AFHTTPSessionManger)
网络状态监听模块(Reachability)
网络通信安全策略模块(Security)
网络通信信息序列化/反序列化模块(Serialization)
对于iOS UIKit库的扩展(UIKit)
其核心当然是网络通信模块AFURLSessionManager。大家都知道,AF3.x是基于NSURLSession来封装的。所以这个类围绕着NSURLSession做了一系列的封装。而其余的四个模块,均是为了配合网络通信或对已有UIKit的一个扩展工具包。
这五个模块所对应的类的结构关系图如下所示:
最上层的是AFHTTPRequestOperationManager,我们调用它进行get、post等等各种类型的网络请求
然后它去调用AFURLRequestSerialization【seralz深】做request参数拼装。然后生成了一个AFHTTPRequestOperation实例,并把request交给它。然后把AFHTTPRequestOperation添加到一个NSOperationQueue中。
接着AFHTTPRequestOperation拿到request后,会去调用它的父类AFURLConnectionOperation的初始化方法,并且把相关参数交给它,除此之外,当父类完成数据请求后,它调用了AFURLResponseSerialization把数据解析成我们需要的格式(json、XML等等)。
最后就是我们AF最底层的类AFURLConnectionOperation,它去数据请求,并且如果是https请求,会在请求的相关代理中,调用AFSecurityPolicy做https认证。最后请求到的数据返回。
用NSURLConnection [kə'nekʃən],我们为了获取请求结果有以下三种选择:
1.在主线程调异步接口
2.每一个请求用一个线程,对应一个runloop,然后等待结果回调。
3.只用一条线程,一个runloop,所有结果回调在这个线程上。
问题
一.为什么AF2.x需要一条常驻线程?
1.把它加入`NSRunLoopCommonModes中,试想如果有大量的网络请求,同时回调回来,就会影响我们的UI体验了。
2.另外一点原因是,如果我们请求数据返回,势必要进行数据解析,解析成我们需要的格式,那么这些解析都在主线程中做,给主线程增加额外的负担又或者我们回调回来开辟一个新的线程去做数据解析,那么我们有n个请求回来开辟n条线程带来的性能损耗,以及线程间切换带来的损耗,是不是一笔更大的开销。
3.为什么不去runloop 回调:我们一开始就开辟n条线程去做请求,然后设置runloop保活住线程,等待结果回调。其实看到这,想想都觉得这个方法很傻,为了等待不确定的请求结果,阻塞住线程,白白浪费n条线程的开销。
AFNetworking的作用总结:
首先它帮我们做了各种请求方式request的拼接。想想如果我们用NSURLSession,我们去做请求,是不是还得自己去考虑各种请求方式下,拼接参数的问题。
它还帮我们做了一些公用参数(session级别的),和一些私用参数(task级别的)的分离。它用Block的形式,支持我们自定义一些代理方法,如果没有实现的话,AF还帮我们做了一些默认的处理。而如果我们用NSURLSession的话,还得参照AF这么一套代理转发的架构模式去封装。
它帮我们做了自定义的https认证处理。看过楼主之前那篇AFNetworking之于https认证的朋友就知道,如果我们自己用NSURLSession实现那几种自定义认证,需要多写多少代码...
对于请求到的数据,AF帮我们做了各种格式的数据解析,并且支持我们设置自定义的code范围,自定义的数据方式。如果不在这些范围中,则直接调用失败block。如果用NSURLSession呢?这些都自己去写吧...(你要是做过各种除json外其他的数据解析,就会知道这里面坑有多少...)
对于成功和失败的回调处理。AF帮我们在数据请求到,到回调给用户之间,做了各种错误的判断,保证了成功和失败的回调,界限清晰。在这过程中,AF帮我们做了太多的容错处理,而NSURLSession呢?只给了一个完成的回调,我们得多做多少判断,才能拿到一个确定能正常显示的数据?
光是这些网络请求的业务逻辑,AF帮我们做的就太多太多,当然还远不仅于此。它用凝聚着许多大牛的经验方式,帮我在有些处理中做了最优的选择,比如我们之前说到的,回调线程数设置为1的问题...帮我们绕开了很多的坑,比如系统内部并行创建task导致id不唯一等等...
又或者AFImageDownloader,它对于组图片之间的下载协调,以及缓存使用的之间线程调度。对于线程,锁,以及性能各方面权衡,找出最优化的处理方式
网友评论