本文不对AFNetworking作全面的解析,仅对比解析一下2.x和3.x的差异。
AFNetworking源码分析全套教程点击获取
1. AFNetworking分为如下5个功能模块:
- 网络通信模块(AFURLSessionManager、AFHTTPSessionManger)
- 网络状态监听模块(Reachability)
- 网络通信安全策略模块(Security)
- 网络通信信息序列化/反序列化模块(Serialization)
- 对于iOS UIKit库的扩展(UIKit)
-
AFNetworking 2.x需要常驻线程而3.x不需要常驻线程
2.x常驻线程用来并发请求和处理数据回调,避免多个网络请求的线程开销(不用开辟一个线程,就保活一条线程);而3.x不需要常驻线程是因为NSURLSession可以指定回调delegateQueue,NSURLConnection不行;
NSURLConnection的一大痛点就是:发起请求后,需要一直处于等待回调的状态。而3.x后NSURLSession解决了这个问题;NSURLSession发起的请求,不再需要在当前线程进行回调,可以指定回调的delegateQueue,这样就不用为了等待代理回调方法而保活线程了 -
3.x需要设置最大并发数为1(self.operationQueue.maxConcurrentOperationCount = 1),2.x为什么不需要
功能不一样:3.x的operationQueue是用来接收NSURLSessionDelegate回调的,鉴于一些多线程数据访问的安全性考虑,设置了maxConcurrentOperationCount = 1来达到并发的请求串行的进行回调的效果。而2.x的operationQueue是用来添加operation进行并发请求的,所以不要设置为1
注意:并发数并不等于所开辟的线程数,具体开辟几条线程由系统决定
- 3. x为什么要串行回调
- (AFURLSessionManagerTaskDelegate *)delegateForTask:(NSURLSessionTask *)task { NSParameterAssert(task); AFURLSessionManagerTaskDelegate *delegate = nil; [self.lock lock]; //给所要访问的资源加锁,防止造成数据混乱 delegate = self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)]; [self.lock unlock]; return delegate; }
从代码可以看出,这边对self.mutableTaskDelegatesKeyedByTaskIdentifier的访问进行了加锁,目的是保证多线程环境下的数据安全。既然加了锁,就算maxConcurrentOperationCount不设为1,当某个请求正在回调时,下一个请求还是得等待一直到上个请求获取完所要的资源后解锁,所以这边并发回调也是没有意义的。相反多task回调导致的多线程并发,还会导致性能的浪费
查看原文