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

刚开始被问到 :来你给我讲一下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回调


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,640评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,254评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,011评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,755评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,774评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,610评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,352评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,257评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,717评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,894评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,021评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,735评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,354评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,936评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,054评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,224评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,974评论 2 355

推荐阅读更多精彩内容