AFNetworking源码!解析

AFNetworking源码!解析如果你月入三万的组成是:月薪1万, 另外四套房子租金两万, 绝对不会焦虑.AFNetworking-github原文链接:https://gi

大家好,欢迎来到IT知识分享网。

版权地址:https://www.jianshu.com/p/5f8e56a17d85

作者:有毒的程序猿

说明:八点钟学院二期学员

学院链接:https://ke..com/course/

前言

上海快30岁了月入3W, 为什么还是焦虑?

你焦虑, 是因为你月入三万的姿势不对! 如果你月入三万的组成是:月薪1万, 另外四套房子租金两万, 绝对不会焦虑.

AFNetworking源码!解析

AFNetworking-github原文链接:https://github.com/AFNetworking/AFNetworking

介绍

这篇文章主要对AFNetworking的对外接口和请求处理文件进行阅读, 会拿出里面的优秀的技术点进行介绍.

一、AFHTTPSessionManager

AFHTTPSessionManager类主要是对外提供接口, 通过调用父类方法封装一些常用接口.

AFHTTPSessionManager继承自AFURLSessionManager,并且实现了<NSSecureCoding, NSCopying>两个协议,如果对这两个协议想要深入了解可以进这些查看https://www.jianshu.com/p/c5475f30bb4e

A.NSCoder

- (instancetype)initWithCoder:(NSCoder *)decoder;//解档 扩展 通过XIB创建的一个nib文件,会调用相关类的这个方法- (void)encodeWithCoder:(NSCoder *)coder;//归档+ (BOOL)supportsSecureCoding;支持NSSecureCoding

B.clang warning

#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" //code #pragma clang diagnostic pop

表示在这个区间里忽略一些特定的clang的编译警告,因为AFNetworking作为一个库被其他项目引用,所以不能全局忽略clang的一些警告,只能在有需要的时候局部这样做,所以经常见忽略-Wgnu警告的写法;链接,http://nshipster.com/clang-diagnostics/

C.description

- (NSString *)description { return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, session: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.session, self.operationQueue]; }

相信跟多人跟我一样经常忽略description,它是NSObject
里面带的一个属性,并且携带了一个方法– (NSString *)description. 它就是我们打印对象时所显示的内容,默认状态下, 我们比如打印一个类:

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; NSLog(@"%@", manager);// 不重写description <AFHTTPSessionManager: 0xccc60>// 重写description之后输出的使我们自定制内容 <AFHTTPSessionManager: 0xccc60, baseURL: (null), session: <__NSURLSessionLocal: 0x7faa8f>, operationQueue: <NSOperationQueue: 0xcc60>{name = 'NSOperationQueue 0xcc60'}> 所以我大胆猜测其内部实现 - (NSString *)description { return [NSString stringWithFormat:@"<%@:%p>", NSStringFromClass([self class]),&self]; } 注:这是写框架的一些细节, 可以让使用者通过打印的方式更加具体的看到当前对象的一些状态.

D.NSURLSessionConfiguration

NSURLSessionConfiguration系统提供了三种配置

[1]Configuration options for an NSURLSession. When a session is created, a copy of the configuration object is made - you cannot modify the configuration of a session after it has been created.
    // 在创建Session对象时,可以通过NSURLSessionConfiguration对象来配置Session.Session一旦配置完毕,你就不能够修改.

    [2]The shared session uses the global singleton credential, cache

    and cookie storage objects.

    // Default Session 将cache以及credentials存储于本地。

    [3]An ephemeral session has no persistent disk storage for cookies,

    cache or credentials.

    // Ephemeral Session 则对数据更加保密安全一些, 它不会向本地存储任何信息,所有的cache、credentials 等存在内存中并和Session绑定, 当Session销毁时,所有的相关信息也同时自动销毁。

    [4]A background session can be used to perform networking operations on behalf of a suspended application, within certain constraints.

    // Background Session能够使APP处于后台时,数据继续传输。 其行为与default Session类似,但是所有的数据传输均有一个独立的进程来管理(非本APP)。 同时Background Session也有一些功能上的限制。

    下面三种配置的接口提供

    @interface NSURLSessionConfiguration : NSObject <NSCopying>@property (class, readonly, strong) NSURLSessionConfiguration *defaultSessionConfiguration;@property (class, readonly, strong) NSURLSessionConfiguration *ephemeralSessionConfiguration; + (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));

    二、AFURLSessionManager

    AFURLSessionManager这个类才是对请求发送的核心类.它主要包括AFURLSessionManagerTaskDelegate_AFURLSessionTaskSwizzlingAFURLSessionManager这三个对象.

    <一>AFURLSessionManagerTaskDelegate

    这个类分发处理了AFURLSessionManager主类的上传,下载进度的管理,通过观察task一些方法的变化,来得到进度.而且还帮忙处理了

    NSURLSessionTaskDelegateNSURLSessionDataTaskDelegateNSURLSessionDownloadTaskDelegate 等代理的返回数据.

    A.NSProgress

    // 进度暂停回调@property (nullable, copy) void (^pausingHandler)(void);// 进度恢复回调@property (nullable, copy) void (^resumingHandler)(void) NS_AVAILABLE(10_11, 9_0); 注:AFNetworking 对进度的管理也用到了NSProgress,并实现了进度的暂停及恢复.

    这里(https://www.jianshu.com/p/afda5c)对NSProgress已经做了详细的介绍我不再多做解释.

    <二>_AFURLSessionTaskSwizzling

    这个类在#issues 1477上reopen了多次,讨论还是很激烈的。讨论的起由是app会莫名crash,主要原因是AFNetworking对NSURLSessionTask中的state进行了KVO操作。一开始人们removeObserver这个state,但是会造成AFNetworkActivityIndicatorManager功能(其中会观察state)削弱。另外后来iOS8上也出现了同样crash现象,貌似iOS7和iOS8在NSURLSessionTask有些不同。最后还是有个大神用swizzling方法才解决了这个问题。

    A.任务状态监听

    AFNetworking巧妙的运用runtime的方法交换在+load中给NSURLSessionTask的两个方法注入监听.

    - (void)suspend; - (void)resume;

    AFNetworking源码!解析

    - (void)af_resume { NSAssert([self respondsToSelector:@selector(state)], @"Does not respond to state"); NSURLSessionTaskState state = [self state]; [self af_resume]; if (state != NSURLSessionTaskStateRunning) { // 这有点不明白这个讨论恒成立state = NSURLSessionTaskStateCanceling; // 发送重新开始通知 用于网路指示器的设置 [[NSNotificationCenter defaultCenter] postNotificationName:AFNSURLSessionTaskDidResumeNotification object:self]; } }

    <三>AFURLSessionManager

    A.NSURLSession与NSURLConnection

    NSURLSession在iOS7.0时被Apple提出后, 虽然Apple一直对其良好的API设计大力推广, 然而其能够达到的效果, 似乎一直都和NSURLConnection不相伯仲.由于AFNetworking优秀的架构设计, NSURLSession甚至还不如NSURLConnection好用. 那么,有什么理由切换到NSURLSession? 2015年的WWDC似乎告诉了我们答案.HTTP /2, 2015年5月RFC 7540正式发表的下一代HTTP协议, 是1999年来HTTP 1.1发布后的首个更新. 相对于前一个版本, HTTP /2以快著称.

    AFNetworking源码!解析

    根据2015的WWDC Session71,我们知道iOS9+,NSURLSession开始正式支持HTTP /2,也就意味着你的网络连接速度也可以有如上图那样的提升。

    B.共享NSURLSession思路分析

    现在AFNetworking 内部提供的创建方式[AFHTTPSessionManager manager],每次调用会新建一个NSURLSession,然后新建Task,激活Task,完成网络请求。

    在回答这个问题以前,我们先来聊聊网络的通讯协议。 我们也都知道,HTTP协议是基于TCP协议的。所以在每次的HTTP请求之前,客户端和服务器端, 都先需要经过TCP连接的三次握手,即每次请求之前, 网络的数据都已经在客户端和服务器端之间来回了三次。如下图:

    AFNetworking源码!解析

    事实上在HTTP 0.9, HTTP 1.0协议的时代, 每次HTTP的请求,都需要先经过TCP的连接,然后才开始HTTP的请求. 那么,为了让我们的请求更快,避免每次都产生一个TCP三次握手,成了一个优化的选项。 于是在HTTP 1.1中,出现了Connection: keep-alive这个选项。这个优化选项, 可以使得客户端和服务器端复用一个TCP连接,从而减小每次的网络请求时间。

    没错,共享的NSURLSession将会复用TCP的连接,而每次都新建NSURLSession的操作将导致每次的网络请求都开启一个TCP的三次握手。所以我们封装请求类的时候,最好用单例模式.让manager持有NSURLSession,达到共享的效果.即一个Session
    创建多个Task来实现网路的请求.

    B.delegate的储存

      self.mutableTaskDelegatesKeyedByTaskIdentifier 是一个储存AFURLSessionManagerTaskDelegate的可变字典.用NSLock锁保证了线程安全.

      AFNetworking源码!解析

      C. responseSerializer

       /** 当数据传输任务用“GET”、“POST”等方式时,在“dataTaskWithRequest:success:failure:”方法里创建的一个从服务器发回的响应。 默认情况下,此属性设置为“AFJSONResponseSerializer”的一个实例。 @warning “responseSerializer”必须不为空. */ @property (nonatomic, strong) id <AFURLResponseSerialization> responseSerializer;

      AFHTTPRequestSerializerAFHTTPResponseSerializer 都遵循了<AFURLResponseSerialization>协议.

      为什么这里提到这个呢, 这种通过协议来整合不同工具的方法,很值得借鉴. 在以后的文章中会详细介绍这两个类.

      谢谢观赏。

      免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/59341.html

      (0)

      相关推荐

      发表回复

      您的邮箱地址不会被公开。 必填项已用 * 标注

      关注微信