版权地址: https://www.jianshu.com/p/5f8...
做者:有毒的程序猿
说明:八点钟学院二期学员
学院学习连接: https://ke.qq.com/course/171725
前言ios
上海快30岁了月入3W, 为何仍是焦虑?git
你焦虑, 是由于你月入三万的姿式不对! 若是你月入三万的组成是:月薪1万, 另外四套房子租金两万, 绝对不会焦虑.github
AFNetworking-github原文连接:https://github.com/AFNetworki...macos
介绍安全
这篇文章主要对AFNetworking的对外接口和请求处理文件进行阅读, 会拿出里面的优秀的技术点进行介绍.服务器
1、AFHTTPSessionManagercookie
AFHTTPSessionManager类主要是对外提供接口, 经过调用父类方法封装一些经常使用接口.网络
AFHTTPSessionManager继承自AFURLSessionManager,而且实现了<NSSecureCoding, NSCopying>两个协议,若是对这两个协议想要深刻了解能够进这些查看https://www.jianshu.com/p/c54...session
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-di...
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: 0x6000001ccc60>// 重写description以后输出的使咱们自定制内容<AFHTTPSessionManager: 0x6000001ccc60, baseURL: (null), session: <__NSURLSessionLocal: 0x7faa8f706420>, operationQueue: <NSOperationQueue: 0x60400003cc60>{name = 'NSOperationQueue 0x60400003cc60'}>因此我大胆猜想其内部实现- (NSString *)description { return [NSString stringWithFormat:@"<%@:%p>", NSStringFromClass([self class]),&self]; } 注:这是写框架的一些细节, 可让使用者经过打印的方式更加具体的看到当前对象的一些状态.
D.NSURLSessionConfiguration
NSURLSessionConfiguration系统提供了三种配置
[1]Configuration options for an NSURLSession. When a session iscreated, 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));
2、AFURLSessionManager
AFURLSessionManager这个类才是对请求发送的核心类.它主要包括AFURLSessionManagerTaskDelegate、_AFURLSessionTaskSwizzling、AFURLSessionManager这三个对象.
<一>AFURLSessionManagerTaskDelegate
这个类分发处理了AFURLSessionManager主类的上传,下载进度的管理,经过观察task一些方法的变化,来获得进度.并且还帮忙处理了
NSURLSessionTaskDelegate、NSURLSessionDataTaskDelegate和NSURLSessionDownloadTaskDelegate 等代理的返回数据.
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/239...
<二>_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的两个方法注入监听.
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以快著称.
根据2015的WWDC Session71,咱们知道iOS9+,NSURLSession开始正式支持HTTP /2,也就意味着你的网络链接速度也能够有如上图那样的提高。
B.共享NSURLSession思路分析
如今AFNetworking 内部提供的建立方式[AFHTTPSessionManager manager],每次调用会新建一个NSURLSession,而后新建Task,激活Task,完成网络请求。
在回答这个问题之前,咱们先来聊聊网络的通信协议。咱们也都知道,HTTP协议是基于TCP协议的。因此在每次的HTTP请求以前,客户端和服务器端,都先须要通过TCP链接的三次握手,即每次请求以前,网络的数据都已经在客户端和服务器端之间来回了三次。以下图:
事实上在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锁保证了线程安全.
C. responseSerializer
/* 当数据传输任务用“GET”、“POST”等方式时,在“dataTaskWithRequest:success:failure:”方法里建立的一个从服务器发回的响应。 默认状况下,此属性设置为“AFJSONResponseSerializer”的一个实例。 @warning “responseSerializer”必须不为空. / @property (nonatomic, strong) id <AFURLResponseSerialization> responseSerializer;
AFHTTPRequestSerializer 和AFHTTPResponseSerializer 都遵循了<AFURLResponseSerialization>协议.
为何这里提到这个呢, 这种经过协议来整合不一样工具的方法,很值得借鉴. 在之后的文章中会详细介绍这两个类.
谢谢观赏。