首先说一下AFNetworking的github地址:GitHub - AFNetworking/AFNetworking: A delightful networking framework for iOS

最近抓时间研究了一下AFNetworking,目前版本是3.1.0,我通过CocoaPods导入的AFNetworking,导入后目录如下

使用CocoaPods导入后可以看到目录很清晰主要是在五个文件夹下,NSURLSession,ReachAbility,Security,Serialization和UIKit。当不使用CocoaPods的时候会显示两个文件夹

很明显第一个文件夹里边是跟网络请求相关的,第二个是跟UI相关的。我主要看了一下与网络请求相关的类。

下面就按照CocoaPods导入显示出来文件夹顺序进行介绍

这里我先讲AFURLSessionManager这个类,主要提供了数据的请求、上传和下载功能

在.h中注释中介绍AFURLSessionManager创建并且管理一个NSURLSession对象,这个对象是基于一个规定的NSURLSessionConfiguration对象,遵循协<NSURLSessionTaskDelegate>, <NSURLSessionDataDelegate>, <NSURLSessionDownloadDelegate>, and <NSURLSessionDelegate>.

下面先将一下当中的属性

session就是要管理的NSURLSession对象,operationQueue是操作队列,当代理回调的时候运行

通过这四个属性,我们分别可以拿到总的任务集合(包括上传和下载任务)、数据任务集合、上传任务集合和下载任务集合

如上图所示,注释里面写到,在iOS7中存在一个bug,在创建后台上传任务时,有时候会返回nil。作为一个修补方案,如果设置这个属性为YES, AFNetworking将会遵照苹果的建议,在创建失败的时候,会重新尝试创建,次数默认为3次。所以你的应用如果有在后台上传的情况的话,记得将该值设为YES,避免出现上传失败的问题。

下面是好多方法,由于方法太多就不一一进行介绍了,可以参考方法上边的注释。

之后我们可以看到很多常量,这些是通知的key。

可以看到定义常量都是用的FOUNDATION_EXPORT,通过观看iOS开发的一些奇巧淫技3这篇文章可以知道FOUNDATION_EXPORT在c文件编译下是和extern等同,在c++文件编译下是和extern “C”等同,在32位机的环境下又是另外编译情况,在兼容性方面,FOUNDATION_EXPORT做的会更好。

在.m文件中定义是这样的常量是这样的

到这里.h文件讲解完


下面介绍一下实现文件,先讲几个在AF中的开发技巧

1.为保证线程安全,所有单例都用dispatch_once生成,保证只执行一次,代码如下

2.我们经常看到一个 block 要使用 self,会处理成在外部声明一个 weak 变量指向 self,在 block 里又声明一个 strong 变量指向 weakSelf:

weakSelf是为了block不持有self,避免循环引用,而再声明一个strongSelf是因为一旦进入block执行,就不允许self在这个执行过程中释放。block执行完后这个strongSelf会自动释放,没有循环引用问题。

3.

#pragma clang diagnostic push

#pragma clang diagnostic ignored "-Wgnu"

代码中间有   ?:

#pragma clang diagnostic pop

消除警告,上一篇中有介绍http://www.cnblogs.com/qiutangfengmian/p/5644133.html

下面讲一下代码,一层一层进行剖析。

我们可以看到在外部API调用dataTask、uploadTask、downloadTask方法实际上都是completionHanlder block返回出来的,但是我们知道网络请求是delegate返回结果的,AF内部做了巧妙的操作,他对每个task都增加代理设置

在设置里面,每个task会在内部创建AFURLSessionManagerTaskDelegate对象,并设置completionHandler、uploadProgressBlock、downloadProgressBlock回调

然后delegate对象利用kvo将task对一些方法进行监听,并且监听到变化时,通过block返回,将delegate转成block出去

setupProgressForTask方法主要是对task和progress设置监听

这一段代码主要是设置上传任务的大小,下载任务的大小,上传任务进行时可以取消,可以暂停,上传任务响应恢复处理方法后恢复上传。

这一段代码主要是设置下载任务进行时可以取消,可以暂停,下载任务响应恢复处理方法后恢复下载。

最后,task对接收到的字节数、期望接收到的字节数、发送的字节数、期望发送的字节数设置监听,对上传和下载进程完成的分数进行监听。

在这个方法中处理变更通知,这是kvo-键值观察者模式。change中是变更信息,具体是哪些信息取决于注册时的 NSKeyValueObservingOptions。

在第一个if判断里面,object判断是否是NSURLSessionTask类或者是否是NSURLSessionDownloadTask类,然后在if条件下  设置上传和下载的任务的新的大小。当我们进到NSURLSessionDownloadTask的时候,我们可以看到NSURLSessionDownloadTaskNSURLSessionTask的子类,那为什么还要进行两个类的判断呢?

NSURLSessionTask实际上是Class cluster(类簇),通过NSURLSession生成的task返回的并不一定是指定的task类型。因此kindOfClass并不总会生效,具体可以参见AFURLSessionManager.m在load方法中的说明
特定于当前问题,是由于iOS 7上NSCFURLSessionDownloadTask的基类并不是NSCFURLSessionTask,因此isKindOfClass会出错。查看对应的commit就可以知道了。


下面讲一下代理方法NSURLSessionTaskDelegate

下面这两个代理方法在@implementation AFURLSessionManager中

这个方法表示将会执行HTTP重定向,如果taskWillPerformHTTPRedirection存在就执行block,如果completionHandler存在就执行它。都是block.

在这个方法中如果代理存在,就执行下边的这个方法,然后把代理移除,任务完成执行taskDidComplete方法。和上边的方法相比第一个参数类型为NSURLSession, 上、下边的是__unused NSURLSession。__unused修饰的参数意义为这个参数可能不会被用到,编译的时候不用发出警告。

这个方法在@implementation AFURLSessionManager中,下面这个方法在@implementation AFURLSessionManagerTaskDelegate当中,两个都遵守协议NSURLSessionTaskDelegate。所以在上面方法中代理运行执行下面方法,需要实现相同方法,只是方法中内容不同。

这里将responseSerializer和downloadFileURL或data存到userInfo里面。

根据error是否为空值,做下一步处理。在有error时,userInfo先存储error,然后检查manager是否有completionGroup和completionQueue,没有的话,就创建一个dispatch_group_t和在主线程上做completionHandler的操作,并在主线程中发送一个AFNetworkingTaskDidCompleteNotification通知,这个通知在UIKit+AFNetworking里UIRefreshControl +AFNetworking里也会接收到,用来停止刷新,如果你不使用AF的UI部分,你可以通过接收这个通知来做操作。

在没有error时,会先对数据进行一次序列化操作,然后下面的处理就和有error的那部分一样了。

这两个方法是收到数据和下载文件的回调处理

上面几个代理方法均在@implementation AFURLSessionManager中。

如有转载,请注明出处。

参考资料:

http://zeeyang.com/2016/02/21/AFNetWorking-one/

AFNetworking (3.1.0) 源码解析 <一>的更多相关文章

  1. AFNetworking (3.1.0) 源码解析 <三>

    今天要介绍的是Reachability文件夹下的AFNetworkReachabilityManager类.通过字面意思我们就可以知道AFNetworkReachabilityManager是用来监测 ...

  2. AFNetworking2.0源码解析<三>

    本篇说说安全相关的AFSecurityPolicy模块,AFSecurityPolicy用于验证HTTPS请求的证书,先来看看HTTPS的原理和证书相关的几个问题. HTTPS HTTPS连接建立过程 ...

  3. AFNetworking (3.1.0) 源码解析 <六>

    这次继续介绍文件夹Serialization下的类AFURLResponseSerialization.这次介绍就不拆分了,整体来看一下.h和.m文件. 协议AFURLResponseSerializ ...

  4. AFNetworking (3.1.0) 源码解析 <五>

    这次主要开始讲解一下文件夹Serialization下的类AFURLRequestSerialization. AFURLRequestSerialization类遵守`AFURLRequestSer ...

  5. AFNetworking (3.1.0) 源码解析 <四>

    这次主要看一下文件夹Security中的类AFSecurityPolicy----安全策略类. AFSecurityPolicy主要的作用是验证HTTPS请求证书的有效性,在iOS9之后,默认不能发送 ...

  6. AFNetworking (3.1.0) 源码解析 <二>

    这次讲解AFHTTPSessionManager类,按照顺序还是先看.h文件,注释中写到AFHTTPSessionManager是AFURLSessionManager的子类,并且带有方便的HTTP请 ...

  7. solr&lucene3.6.0源码解析(三)

    solr索引操作(包括新增 更新 删除 提交 合并等)相关UML图如下 从上面的类图我们可以发现,其中体现了工厂方法模式及责任链模式的运用 UpdateRequestProcessor相当于责任链模式 ...

  8. Heritrix 3.1.0 源码解析(三十七)

    今天有兴趣重新看了一下heritrix3.1.0系统里面的线程池源码,heritrix系统没有采用java的cocurrency包里面的并发框架,而是采用了线程组ThreadGroup类来实现线程池的 ...

  9. solr&lucene3.6.0源码解析(四)

    本文要描述的是solr的查询插件,该查询插件目的用于生成Lucene的查询Query,类似于查询条件表达式,与solr查询插件相关UML类图如下: 如果我们强行将上面的类图纳入某种设计模式语言的话,本 ...

随机推荐

  1. css.day02

    1.复合选择器 复合选择器 一般会有几个标签混合使用 .把多个组合成一个  称之为复合 1.1标签指定式 复合选择器 (交集选择器) 格式: 标记选择器+ 类名/ID名称 { 属性:值;} 实际情况用 ...

  2. 关于asp.net C# 导出Excel文件 打开Excel文件格式与扩展名指定格式不一致的解决办法

    -----转载:http://blog.csdn.net/sgear/article/details/7663502 关于asp.net C# 导出Excel文件 打开Excel文件格式与扩展名指定格 ...

  3. updatepanel的用法之triggers

    triggers有的两种触发器asyncpostbacktrigger和postbacktrigger.asyncpostbacktrigger(异步回调触发器):局部刷新,只刷新updatepane ...

  4. Android项目代码混淆

    http://coolshell.info/blog/2015/03/Android-studio-prefrence.html 什么是Gradle Gradle是一种依赖管理工具,基于Groovy语 ...

  5. 使用NPOI插件读取excel模版修改数据后保存到新目录新文件中

    添加引用: using System.IO; using NPOI.XSSF.UserModel; using NPOI.SS.UserModel; using NPOI.HSSF.UserModel ...

  6. 使用POI进行Excel操作的总结一——创建Workbook,Sheet,Row以及Cell

    前段时间,看在其他的网站上给出Excel文档的导入与导出操作,感觉很酷的样子,所以就学习了一下如何使用POI进行Excel的操作,现在对之前的学习过程进行一个总结. 一.现在普遍使用的Excel文档有 ...

  7. 【HAOI2007】理想的正方形

    [问题描述] 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. [输入] 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行 ...

  8. asp.net实现 EXCEL数据导入到数据库功能

    在项目中经常要用EXCEL导入数据到数据库,提高工作效率. 注意:EXCEL中的第一行不能导入. 下面是源码: IntoExcel.aspx: [csharp] <%@ Page Languag ...

  9. JavaScript 的setAttribute兼容性解决

    setAttribute各个浏览器都支持,但在IE7以下版本中,有些属性值还是有差异的,比如 obj.setAttribute("class","classname&qu ...

  10. python:open/文件操作

    open/文件操作f=open('/tmp/hello','w') #open(路径+文件名,读写模式) #读写模式:r只读,r+读写,w新建(会覆盖原有文件),a追加,b二进制文件.常用模式 如:' ...