AFNetworking - AFURLSessionManager 源码解读

567 阅读3分钟

AFNetworking

核心通讯类 NSURLSession

AFURLSessionManager

核心方法

遵循了NSURLSession相关的各个协议 , 协议方法的触发是根据 task的类型来触发

	- NSURLSessionDelegate
	- NSURLSessionTaskDelegate
	- NSURLSessionDataDelegate
	- NSURLSessionDownloadDelegate

实例化方法initWithSessionConfiguration

通过 request 和 url来创建不同的task的一系列方法

持有的重要实例对象

会话对象 session

  NSURLSession实例变量, AFN的所有网络请求都必须通过 session创建的task实现

回调时的控制队列 operationQueue

  控制session绑定的代理方法 或者block回调的 队列, 默认最大并发为1, 串行队列

返回数据序列化对象 responseSerializer

  遵循了 AFURLResponseSerialization协议, 会自动进行验证和序列化 从服务端得到的数据

安全信任对象 securityPolicy

  AFSecurityPolicy 对象, 用来进行安全验证的类

网络状态监听对象 reachabilityManager

  网络状态监听对象, AFNetworkReachabilityManager

task管理的数组对象 tasks, dataTasks, uploadTasks, downloadTasks

  • tasks数组 是 session中所有 currently run的 task的管理数组
    
  • dataTasks 是 currently run的所有请求数据类task的纪录管理数组
    
  • uploadTasks是currently run的所有上传文件类的task的纪录管理数组
    
  • downloadTasks 是currently run的所有下载文件类的task的纪录管理数组
    

相关联的主要类

task中相关操作的管理类 AFURLSessionManagerTaskDelgate

AFURLSessionManagerTaskDelegate 类是对每次请求中task的相关处理的封装, 每一个任务(task) 都和对应的 delegate对象 绑定, 并以task.identifier为key, delegate对象为值, 通过key-value的方式被 AFURLSessionManager中的mutableTaskDelegatesKeyedByTaskIdentifier所管理

  • 对数据上传,数据下载进度的监听的实现
    
  • 也做了下载数据的存储路径的置顶
    
  • 对网络请求,下载,上传等task(任务)完成后的回调处理
    

但它不是直接被会话对象(NSURLSession)处理的, 而是在AFURLSessionManager中实现的 NSURLSession相关的各个协议被触发后,再根据当前的task 找到与之绑定的 AFURLSessionManagerTaskDelegate对象, 然后交给AFURLSessionManagerTaskDelegate对象去处理下一步的处理; 这里就完全提现了 AFURLSessionManagerTaskDelegate类的作用; (大神的设计思路真是令人膜拜!)

_AFURLSessionTaskSwizzling

_AFURLSessionTaskSwizzling 存在的目的是为了解决在OS7和iOS8中NSURLSessionTask的父类不同的问题; 通过runtime的原理,在load()方法中实现了 resume()和suspend()方法与 af_resume()和af_suspend方法的替换处理,这样就解决了在iOS7和iOS8中因为NSURLSessionTask父类不同导致resume和suspend不统一的问题

AFHTTPSessionManager

继承于AFURLSessionManager, 是AFN中对HTTP相关请求的封装类, 主要提供了方便我们进行POST, GET,HEAD, PATCH, DELETE的一些方法;

  • 实例化方法 manager, manager方法采用的并不是单利设计模式,而是工厂设计模式
//详细代码
+ (instancetype)manager {
    return [[[self class] alloc] initWithBaseURL:nil];
}
- (instancetype)init {
    return [self initWithBaseURL:nil];
}
- (instancetype)initWithBaseURL:(NSURL *)url {
    return [self initWithBaseURL:url sessionConfiguration:nil];
}
- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
    return [self initWithBaseURL:nil sessionConfiguration:configuration];
}

在AFURLSessionManager中注意到的知识点

weak关键字的使用, 用来防止循环引用
@interface AFURLSessionManagerTaskDelegate : NSObject <NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>
//weak的使用(manager持有task,task和delegate是绑定的,相当于manager是持有delegate的),在这种场景中采用 weak关键字来修饰
@property (nonatomic, weak) AFURLSessionManager *manager;
@end
将回调操作的block @property 属性化到 AFURLSessionManager.h中, 并重新在AFURLSessionManager.m中set方法重写, 方便被外部调用的设计思路
代码举例:
@interface AFURLSessionManager ()
@property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidReceiveResponseBlock dataTaskDidReceiveResponse;
@end

@implementation AFURLSessionManager
- (void)setDataTaskDidReceiveResponseBlock:(NSURLSessionResponseDisposition (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response))block {
    self.dataTaskDidReceiveResponse = block;
}
@end

AFURLSessionManagerTaskDelgate类的设计, 让AFURLSessionManager管理 task和与之相对应的 AFURLSessionManagerTaskDelgate 对象, 将每个task最后的数据处理, 进度处理转移到 AFURLSessionManagerTaskDelgate 实例化对象中, 让整个流程思路变得非常清晰明了