美文网首页
说说你会用但是不了解的好朋友

说说你会用但是不了解的好朋友

作者: 废物也要再利用 | 来源:发表于2016-11-20 18:06 被阅读0次

刚开始被问到 :来妹妹~你给我讲一下AF

顿时一脸懵逼 有时候你懂得一个东西是做什么的 但是又不会去想为什么这么做 真的很尴尬呐

来看看官方介绍:

AFNetworking is a delightful networking library for iOS and Mac OS X. It’s built on top of theFoundation URL Loading System, extending the powerful high-level networking abstractions built into Cocoa. It has a modular architecture with well-designed, feature-rich APIs that are a joy to use.

Perhaps the most important feature of all, however, is the amazing community of developers who use and contribute to AFNetworking every day. AFNetworking powers some of the most popular and critically-acclaimed apps on the iPhone, iPad, and Mac.

Choose AFNetworking for your next project, or migrate over your existing projects—you’ll be happy you did!

简单翻译一下:AFNetworking是一个适用于iOS和Mac OS X两个平台的网络库 是基于Foundation URL Loading System上的一套封装 并且提供了丰富优美的API接口给使用者使用

一听就很了不起

选择AFNetworking 版本3.0 逐字逐句的去了解 由于本人不是很喜欢逗号分号这类的 所以全篇无逗号分号 能看就看

没办法Swift惯的~摊手

那就从源码开始说起

用AF3.0的举

拿AFURLSessionManager开刀

以上的属性 可以分别拿到的是:总的任务集合、数据任务集合、上传任务集合和下载任务集合

上面的属性非常重要 特意把注释一起放上来 注释里写到:iOS7中存在一个bug 在创建后台上传任务时  有时候会返回nil 所以为了解决这个问题 AFNetworking遵照里苹果的建议 在创建失败的时候 会重新尝试创建 次数默认为3次 所以你的应用如果有场景会在后台上传的情况的话 记得将该值设为YES 避免出现上传失败的问题

*AFNetworking是对NSURLConnection和NSURLSession的各自一层包装

—AFNetworking的内部中的RunLoop

AFNetworking内部开辟一条专门用来访问网络请求的线程

在这个开线程的方法中 他把方法和dispatch _once 都用static修饰

以保证这个方法的安全性以及开笔一块内存空间 病区保证线程不死

在这个方法中他会调用另一个网络请求的方法

在Xcode 7之后 NSURLConnection的API已经正式被苹果遗弃 虽然还可以使用 但是新功能不会再被添加

意味着什么 意味着已经放弃了对其维护 那么就好好告别吧

所以之前熟悉的好朋友:

AFURLConnectionOperation

AFHTTPRequestOperation

AFHTTPRequestOperationManager

这些类已经从3.0中废弃

AFURLSessionManager继承自NSObject 服从

NSURLSessionDelegate

NSURLSessionTaskDelegate

NSURLSessionDataDelegate

NSURLSeesionDownloadDelegate

NSSecureCoding

NSCopying

以上协议

是用来NSURLSession的封装单元

AFURLSessionManager中包含三个部分:

AFURLSessionManagerTaskDelegate:用来管理网络请求的信息 并且处理请求完成的回调

_AFURLSessionTaskSwizzling:用来完成resume与af_resume的swizzling的类

AFURLSessionManager:主体控制网络请求的相关功能在AFURLSessionManager中 创建一个NSOperationQueue 最大operation数为1

规定请求delegate的OperationQueue是唯一的  在这个类中开辟了唯一的一个串行队列url_session_manager_creation_queue来调用NSURLSession的请求方法 唯一的一个并行队列url_session_manager_processing_queue来进行编程 使用唯一的一个group url_session_manager_completion_group来管理完成线程

为了保证线程安全 所以得到的单例都是使用dispatch_once生成

并且通过KVO监控resume情况

调用网络请求的方法中 会创建一个NSURLSessionDataTask对象 用来返回给用户 在之前单例创建的线程中 url_session_manager_creation_queue调用init中创建的session属性来执行请求中的方法

由-(void)addDelegateForDataTask可以看出来在框架中用于管理请求信息与数据的回调的事AFURLSessionManagerTaskDelegate

AFURLSessionManagerTaskDelegate和NSURLSessionTask的关系是由AFURLSessionManager管理的

addDelegateForDataTask方法中除了创建AFURLSessionManagerTaskDelegate类鱼配置其属性以外 如果是上传 会配置content-length以及delegate.progress的相关block属性

如果是下载 则会配置download的block属性

之后的一个方法是setDelegate:forTask:它将AFURLSessionManagerTaskDelegate与NSURLSessionDataTask进行了绑定 方便之后对于请求数据的查找与回调

mutableTaskDelegatesKeyedByTaskIdentifier是将task的taskIdentifier与delegate绑定的重要属性

我们想要得到包括进程等等属性都在delegate里面可以得到

在resume时需要外界能接到一个didResume的消息 所以需要调用taskDidResume方法

终于得到了AFNetworkingTaskDidResumeNotification 有了它久方便多了 AFNetworkingTaskDidSuspendNotification也是同理

在这里其实还有一个很重要的知识点 :

AFNetworking对NSURLSessionTask中的state进行了KVO处理

但是在iOS8上会导致莫名的crash 可能是由于iOS7与iOS8上的NSURLSessionTask是不同的

还好可以用swizzling解决这个问题 在源码中我们可以看到如果想要得到AFNetworkingTaskDidResumeNotification通知 就要执行

-(void)taskDidResume:(NSNotification *)notification 方法

而这个方法是需要通过监听AFNSURLSessionTaskDidResumeNotification 来通知执行的

所以我们需要对resume方法进行修改 在resume方法中添加此通知 于是就通过swizzling

在+(void)load 中将af_resume与resume 方法的imp进行交换

af_resume方法实现

简单来说就是将af_resume的函数指针与resume的函数指针进行调换 在调用resume方法时其实就是调用的就是af_resume方法 调用af_resume时则相反

在网络请求的过程中 AFURLSessionManager在执行相关的NSURLSessionDelegate方法时 回调用这个请求相对应的AFURLSessionManagerTaskDelegate类中的对应的NSURLSessionDelegate方法 在AFURLSessionDelegate方法 在AFURLSessionManagerTaskDelegate中完成请求的信息和数据回调

AFURLSessionManager中的NSURLSessionDelegate回调

在AFURLSessionManagerTaskDelegate中的complete方法中则创建一个userInfo字典 存储网络请求的相关信息 然后通过消息中心post AFNetworkingTaskDidCompleteNotification 消息将userInfo传出

其中 还在completionGroup中调用主线程通过执行completionHandler将请求数据传出

到此为止终于完成了一次完整的网络请求

AFURLSessionManagerTaskDelegate中的NSURLSessionDelegate回调

相关文章

网友评论

      本文标题:说说你会用但是不了解的好朋友

      本文链接:https://www.haomeiwen.com/subject/hvhypttx.html