iOS源码补完计划-AFNetworking 3.1.0源码研读

参拜一下AFNetworking的源码。

第四篇源码、暂时来看也是iOS方向的最后一篇、撸完准备趁着热乎撸一撸网络协议。

准备工作

功能模块

AFURLSessionManager/AFHTTPSessionManager

在监听属性的时候、可以用NSStringFromSelector(@selector(xxx))这种方式来自动提示。

功能AIP分层

如何防止block循环引用

把NSURLSession众多代理转化成了block

消除编译器clang警告

正则的简便写法

如何做到对外只读、对内读写

核心代码

一些比较有意思的东西

AFNetworkReachabilityManager

关于FOUNDATION_EXPORT和UIKIT_EXTERN的选择

.#if - #esle - #endif

注册键值依赖

四种网络状态

开始暂停

状态改变的回调block

核心代码

知识点

AFSecurityPolicy

__Require_Quiet判断

.cer文件在iOS里如何使用的

三种验证模式

核心代码

知识点

AFHTTPRequestSerializer

AFHTTPResponseSerializer

协议的应用

如何在一个方法中返回两个NSError

NSIndexSet对象

服务器返回的图片是压缩过的

AFURLResponseSerialization协议以及其解码方法

核心代码

知识点

参考资料

准备工作

使用版本3.1.0

推荐在看AFN之前、先了解一下NSURLSession

不然感觉会看的一头雾水、也体会不到AFN的伟大之处

功能模块

除了这四个服务性模块之外、UIKit文件夹下基本是对各种UI控件的扩展。

AFURLSessionManager/AFHTTPSessionManager

AFURLSessionManager流程

承接了主要的网络传输任务、实现了NSURLSession绝大部分的代理方法。

核心代码

一些比较有意思的东西

在监听属性的时候、可以用NSStringFromSelector(@selector(xxx))这种方式来自动提示。

因为属性本身就是与其get方法同名、可以降低出错概率。

功能AIP分层

AFURLSessionManager实现了所有的NSURLSessionDelegate。但同时又将其中某些需要处理复杂逻辑的代理传递给了AFURLSessionManagerTaskDelegate。使得代码更清晰、逻辑更明确。需要注意的是、AFURLSessionManagerTaskDelegate完全包裹在了AFURLSessionManager内部、外界完全感受到他的存在。但是又能做数据处理、这个架构设计真心很赞。

除此之外、AFURLSessionManager与AFHTTPSessionManager之间也做了很好的分层。

你可以单独使用AFURLSessionManager进行网络会话、也可以通过AFHTTPSessionManager更好的使用AFURLSessionManager进行HTTP请求。

如何防止block循环引用

其实我几年前就听说AFN可以防止循环引用、但是一直没看。

今天找了找发现似乎已经没有了这段代码,所以个人推测现在不会引起循环引用的原因、应该是因为AFN都在作为单例使用、和self并不互相持有。

贴一段以前别人帖子里的代码:

把NSURLSession众多代理转化成了block

这个说实话我并不太暂停...

个人感觉block就是应该控制个数、而NSURLSession的代理加起来起码有二三十个。

如果到了这种数量级的数据传递、真的还是用代理吧、饶了我。

消除编译器clang警告

其中Wgnu可以换成其他具体命令

正则的简便写法

讲道理我还真第一次见

如何做到对外只读、对内读写

AFNetworkReachabilityManager

AFN中负责网络状态模块。在不同的网络状态下可以监听、或者实时查询、并且需要手动开启或者关闭。

四种网络状态

未知、无网络、运营商网络、WiFi网络

开始暂停

状态改变的回调block

知识点

关于FOUNDATION_EXPORT和UIKIT_EXTERN的选择

都可以代替宏来定义常量

有人说是如果文件基于FOUNDATION则用前者、反之则用后者。

二者都能替代#define、并且通过地址比对常量(也就是可以通过 == 直接进行比较)、效率更高。

#if - #esle - #endif

用普通的if-else也是一样、好处就是在编译阶段是否会被编译。

不过、#if - #esle - #endif不能用来判断一个动态的语法。

注册键值依赖

KVO的一个冷门方法

当return的 值被改变的时候、触发key的监听,也就是说当networkReachabilityStatus改变的时候、reachable/reachableViaWWAN/reachableViaWiFi的KVO监听都将被触发

AFSecurityPolicy

负责网络安全策略(证书)的验证模块

核心代码

.cer文件在iOS里如何使用的

整个验证都是基于SecTrustRef的、和.cer文件的关系大概是:

NSData格式的证书==>SecCertificateRef==>SecTrustRef对象

而SecTrustRef、就是一个内部至少携带了证书与公钥的结构体。

三种验证模式

无条件信任服务器的证书、对公钥验证、对证书验证的具体逻辑。

其实整个模块也没有太多可以研究的地方、因为都是固定的方法。你只能这么写~

不过、一行一行看一看。iOS的证书到底是如何验证的、也不错。

知识点

__Require_Quiet判断

宏__Require_Quiet和__Require_noErr_Quiet作用其实和if-esle差不多、但是可以从多个入口跳到统一的出口、相关函数__Require_XXX基本都是这个意思。写了几个小方法、想看的自己可以copy运行一下

这样、我们就有了三种判断的方式

1、普通逻辑的if-else

2、编译级别的#if - #esle - #endif

3、__Require_XXX这种多入口、统一出口的宏判断

AFHTTPRequestSerializer

负责网络请求NSMutableURLRequest对象的初始化以及请求头、请求体、参数、上传文件的自动化配置。几千行代码、很长。但是读下来会受益匪浅。

流程图

AFHTTPRequestSerializer流程图

流程看起来很简单、但是具体实施起来却有很多东西。

包括如何将参数字典转化成字符串并且转译、如何进行文件的分段拼接拷贝、如何将一个个请求体文件整合到request中等等。

AFHTTPResponseSerializer

主要看了看AFURLResponseSerialization的内容,负责网络请求成功之后服务器返回的响应体进行格式化。

核心代码

AFURLResponseSerialization协议以及其解码方法

针对不同的解析器(JSON/XML/PList等)、通过实现这个协议的方式。

在请求结束时、帮助AFURLSessionManager对获得的响应体进行解析。

知识点

1、协议的应用

通过让多个对象遵循同一份协议的方式、可以在解耦的时候代替继承、然后重载父类方法时通用做法。使得一个协议、返回不同的结果。

在多人协作的时候、约定好协议然后交由其他业务实现、也是提升开发效率很普遍的方式。

2、如何在一个方法中返回两个NSError

可以使用嵌套的方式、比如NSUnderlyingErrorKey来指定一个最主要的错误。

3、NSIndexSet对象

NSIndexSet这个合集、是NSSet的数字版。

一个无符号整数的集合、内部元素具有唯一性。

内部元素会自动排序

4、服务器返回的图片是压缩过的

服务器返回的图片、需要被解压出bitmap信息。

bitmap的作用在于在将UIImage交付给UIImageView的时候。

如果没有bitmap将会在主线程自动解压一次。

参考资料马在路上:一个写了很多源码解读的大神

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180627B0C91200?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券