zoukankan      html  css  js  c++  java
  • AFNetworking 源码解析

    3.0 之后,就取消了NSOperation的控制。

    因为根据Apple Developer Document的文档 https://developer.apple.com/documentation/foundation/nsurlsession/1411597-sessionwithconfiguration , 初始化NSURLSession的queue有以下的限制

    queue

    An operation queue for scheduling the delegate calls and completion handlers. The queue should be a serial queue, in order to ensure the correct ordering of callbacks. If nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls.

    所以AFnetworking的里面的NSOperationQueue设置如下,达到为串行的效果,注意串行不保证为FIFO。

        self.operationQueue = [[NSOperationQueue alloc] init];
        self.operationQueue.maxConcurrentOperationCount = 1;

    使用NSLock 来保护一个保存taskidentifier的NSMutableDicitionary.

    使用 semphore 来返回正在执行的任务列表 ,利用URLSession里面的接口,形成了一个串行执行的顺序,https://developer.apple.com/documentation/foundation/nsurlsession/1411578-gettaskswithcompletionhandler

    使用_cmd 巧妙的标示不同的函数入口,cmd在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例。

    如果回包里面header 没有content-length表述数据有多大,那么就不能察觉网路请求的进度,一些接口与属性就失效。

    使用+load swizzle 实现监听系统接口某些函数执行的功能,比如URLSession的resume, suspend, 但是由于iOS8,iOS7之间有些继承关系不一样,一些父类会执行名字相同的函数,所以用一个for循环一直替换函数实现,一直到父类没有对应的不同实现的函数为止。这个功能是经过多次艰辛的调试迭代出来的,请看过程https://github.com/AFNetworking/AFNetworking/pull/2702

    使用Runloop,

        SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);

     

     

    [NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes

    选择使用了 

    根据2015的WWDC Session711,我们知道iOS9+NSURLSession开始正式支持HTTP /2,更加人性化API,更加快。

    于是在HTTP 1.1中,出现了Connection: keep-alive。 这个优化选项,可以使得客户端和服务器端复用一个TCP连接,从而减小每次的网络请求时间底层是否重新创建新的tcp连接并不由上层控制,而是urlsession来决定。最大数设定为1时,由于并发数过小,因此只能选择唯一的连接通道。多设置几个并发数,是否复用,取决于当前同时的请求数,以及服务器给你的协商。

    而如果不使用共享,则会每次都开启多个tcp管道,并且最终连接数量不可控 

    NSURLRequestUseProtocolCachePolicy 这个是默认的缓存策略,缓存不存在,就请求服务器,缓存存在,会根据response中的Cache-Control字段判断下一步操作,如: Cache-Control字段为must-revalidata, 则询问服务端该数据是否有更新,无更新的话直接返回给用户缓存数据,若已更新,则请求服务端。

    还有下载进度这个,必须获取回包的header,看里面是否content-length,这样URLSession才能计算出总的长度,才知道百分比。

    如何防止循环引用?http://nelson.logdown.com/posts/2017/03/28/retain-cycle-in-afnetworking

    當我們呼叫 invalidateSessionCancelingTasks: 函式,它會去呼叫 NSURLSession 的 invalidateAndCancel 或 finishTasksAndInvalidate。根據蘋果文件,呼叫這兩個函式之後,NSURLSession 才會斷開它與 delegate 的關聯。至此,才打破 retain cycle。

    解法

    有兩個解法,第一個就是如上所述,記得最後要呼叫 invalidateSessionCancelingTasks: 來結束任務。第二個就是把 AFHTTPSessionManager 寫成 singleton,這樣有 retain cycle 也無所謂了。

        self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];
     
  • 相关阅读:
    百度地图 导航
    设置cookies第二天0点过期
    GDI+一般性错误(A generic error occurred in GDI+)
    图片上传裁剪(asp.net)
    LeetCode_7. Reverse Integer
    LeetCode_1. Two Sum
    JAVA 基础编程练习题50 【程序 50 文件 IO】
    JAVA 基础编程练习题49 【程序 49 子串出现的个数】
    JAVA 基础编程练习题48 【程序 48 加密】
    JAVA 基础编程练习题47 【程序 47 打印星号】
  • 原文地址:https://www.cnblogs.com/studyNT/p/8367651.html
Copyright © 2011-2022 走看看