AFNetworking 4.x 最全的源码说明书(二)

1,372 阅读11分钟

这是第二篇内容,其他内容可以看下方链接:

  • 第一部分是请求和响应的对应代码,包括AFURLRequestSerializationAFURLResponseSerialization
  • 第二部分是URLSession有关的代码,包括AFURLSessionManagerAFHTTPSessionManager
  • 第三部分是辅助的两个类:AFSecurityPolicyAFNetworkReachabilityManager
  • 第四部分UIKit+AFNetworking目录下的有趣内容。

AFURLSessionManager类

这个类用于创建和管理NSURLSession对象,遵守了NSURLSession相关的协议并实现了大部分代理方法。AFURLSessionManager 类中会持有一个NSURLSession对象,而session中每一个task对象又会被一个字典属性管理,字典的keytask.taskIdentifiervalueAFURLSessionManagerTaskDelegate对象。delegate对象负责每个task对象成功后的回调工作。 大致了解一下结构之后,我们来看具体的代码,先是这个类的声明:

// 持有的session对象,每一个manager都有一个session
@property (readonly, nonatomic, strong) NSURLSession *session;
// session协议回调的执行队列,串行队列
@property (readonly, nonatomic, strong) NSOperationQueue *operationQueue;
// response序列化器,默认的是json序列化器
@property (nonatomic, strong) id <AFURLResponseSerialization> responseSerializer;
@property (nonatomic, strong) AFSecurityPolicy *securityPolicy;
#if !TARGET_OS_WATCH
@property (readwrite, nonatomic, strong) AFNetworkReachabilityManager *reachabilityManager;
#endif
// task完成之后,进行回调的队列,默认是主线程队列
@property (nonatomic, strong, nullable) dispatch_queue_t completionQueue;
// task完成之后的group,默认内部创建,group的目的还是外部可以通过notify来监听
@property (nonatomic, strong, nullable) dispatch_group_t completionGroup;

接下来是获取task数组的属性声明:

// 这四个属性都是通过session.getTasksWithCompletionHandler方法获取的,后面会简单看下
@property (readonly, nonatomic, strong) NSArray <NSURLSessionTask *> *tasks;
@property (readonly, nonatomic, strong) NSArray <NSURLSessionDataTask *> *dataTasks;
@property (readonly, nonatomic, strong) NSArray <NSURLSessionUploadTask *> *uploadTasks;
@property (readonly, nonatomic, strong) NSArray <NSURLSessionDownloadTask *> *downloadTasks;

再往下是方法的声明:

// 使用configuration对象进行初始化
// configuration比较常用的是default和background,另外还有不涉及缓存等操作的ephemeral
- (instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER;
// 失效session对象
// cancelPendingTasks:立即取消排队中的task
// resetSession:重置session对象
- (void)invalidateSessionCancelingTasks:(BOOL)cancelPendingTasks resetSession:(BOOL)resetSession;
/* --- 以下是创建task的方法 --- */
// 创建task的方法有好几个,大致就是不同的入参格式,都比较容易理解,不做赘述了
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
                               uploadProgress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
                             downloadProgress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
                            completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject,  NSError * _Nullable error))completionHandler;
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
                                         fromFile:(NSURL *)fileURL
                                         progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
                                completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError  * _Nullable error))completionHandler;
// 下载方法中的destination参数,主要用法是将下载的tmp文件路径和response信息交予我们,我们告知AFN具体要保存到哪个path
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
                                             progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
                                          destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
                                    completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler;
/* ------ */
// 根据task来返回进度,这个进度是通过delegate对象保管的
- (nullable NSProgress *)uploadProgressForTask:(NSURLSessionTask *)task;
- (nullable NSProgress *)downloadProgressForTask:(NSURLSessionTask *)task;

/* --- 以下是一些回调block,有些忽略了,主要列了一些在触发block的同时,也会把事件透传到delegate对象中的方法 ---*/
// 上传数据时周期性触发,显示具体上传了多少字节,会透传到delegate更新具体task的进度
- (void)setTaskDidSendBodyDataBlock:(nullable void (^)(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend))block;
// task完成后触发,同时也会透传到delegate,delegate负责通知调用方,具体逻辑稍后再看
- (void)setTaskDidCompleteBlock:(nullable void (^)(NSURLSession *session, NSURLSessionTask *task, NSError * _Nullable error))block;
// 使用普通task对象下载时收到数据会多次触发(片段下载),透传delegate更新下载进度,需要手动去保存下载的片段数据
- (void)setDataTaskDidReceiveDataBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data))block;
// 使用downloadTask对象下载完成后通过此block可以重设存储路径后通知delegate
- (void)setDownloadTaskDidFinishDownloadingBlock:(nullable NSURL * _Nullable  (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location))block;
// 使用downloadTask对象下载并本地持久化时触发,透传delegate更新下载进度
- (void)setDownloadTaskDidWriteDataBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite))block;
// 续传下载时,透传delegate更新下载进度
- (void)setDownloadTaskDidResumeBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes))block;
...
/* ------ */

通过代码结构可以看到实现文件中除了AFURLSessionManager 类之外,还声明了AFURLSessionManagerTaskDelegate_AFURLSessionTaskSwizzling两个类,所以我们再看下这两个类做了什么,首先是_AFURLSessionTaskSwizzling

// 两个静态方法,用来交换方法和添加方法
static inline void af_swizzleSelector(Class theClass, SEL originalSelector, SEL swizzledSelector) {
    Method originalMethod = class_getInstanceMethod(theClass, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(theClass, swizzledSelector);
    method_exchangeImplementations(originalMethod, swizzledMethod);
}

static inline BOOL af_addMethod(Class theClass, SEL selector, Method method) {
    return class_addMethod(theClass, selector,  method_getImplementation(method),  method_getTypeEncoding(method));
}

+ (void)load {
    // 此处官方注释有详细解释,大致就是说dataTask对象在iOS7和iOS8的继承父类不同,所以只能用这种遍历的方式,把父类和本类resume实现不一致的类进行替换,替换为AFN自己的resume和suspend方法
    // 此处通过一个空类实现+load方式,在程序运行前进行方法替换
    if (NSClassFromString(@"NSURLSessionTask")) {
        // 使用短暂配置的session对象,创建一个localDataTask
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
        NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnonnull"
        NSURLSessionDataTask *localDataTask = [session dataTaskWithURL:nil];
#pragma clang diagnostic pop
        IMP originalAFResumeIMP = method_getImplementation(class_getInstanceMethod([self class], @selector(af_resume)));
        Class currentClass = [localDataTask class];
        // 循环遍历这个task的父类,交换所有方法
        while (class_getInstanceMethod(currentClass, @selector(resume))) {
            Class superClass = [currentClass superclass];
            IMP classResumeIMP = method_getImplementation(class_getInstanceMethod(currentClass, @selector(resume)));
            IMP superclassResumeIMP = method_getImplementation(class_getInstanceMethod(superClass, @selector(resume)));
            if (classResumeIMP != superclassResumeIMP &&
                originalAFResumeIMP != classResumeIMP) {
                [self swizzleResumeAndSuspendMethodForClass:currentClass];
            }
            currentClass = [currentClass superclass];
        }
        [localDataTask cancel];
        [session finishTasksAndInvalidate];
    }
}

+ (void)swizzleResumeAndSuspendMethodForClass:(Class)theClass {
    // 获取空类中自定义方法
    Method afResumeMethod = class_getInstanceMethod(self, @selector(af_resume));
    Method afSuspendMethod = class_getInstanceMethod(self, @selector(af_suspend));
    // 将方法加入到class后,交换原始方法
    if (af_addMethod(theClass, @selector(af_resume), afResumeMethod)) {
        af_swizzleSelector(theClass, @selector(resume), @selector(af_resume));
    }
    if (af_addMethod(theClass, @selector(af_suspend), afSuspendMethod)) {
        af_swizzleSelector(theClass, @selector(suspend), @selector(af_suspend));
    }
}

- (NSURLSessionTaskState)state {
    NSAssert(NO, @"State method should never be called in the actual dummy class");
    return NSURLSessionTaskStateCanceling;
}

- (void)af_resume {
    NSAssert([self respondsToSelector:@selector(state)], @"Does not respond to state");
    NSURLSessionTaskState state = [self state];
    [self af_resume];
    // 注意此时的state为NSURLSessionTaskStateSuspended
    if (state != NSURLSessionTaskStateRunning) {
        [[NSNotificationCenter defaultCenter] postNotificationName:AFNSURLSessionTaskDidResumeNotification object:self];
    }
}

- (void)af_suspend {
    NSAssert([self respondsToSelector:@selector(state)], @"Does not respond to state");
    NSURLSessionTaskState state = [self state];
    [self af_suspend];
    // 注意此时的state为NSURLSessionTaskStateRunning
    if (state != NSURLSessionTaskStateSuspended) {
        [[NSNotificationCenter defaultCenter] postNotificationName:AFNSURLSessionTaskDidSuspendNotification object:self];
    }
}

这个类无非就是使用自定义的resumesuspend方法替换原始方法,目的就是在操作之后,从task对象发送通知到AFURLSessionManager中,再由AFURLSessionManager发送通知到外部调用方。 我并没有弄清楚此处自定义方法中的state状态变化,猜测是调用resume或者suspend方法后state并没有立即改变,如果有研究的大佬可以与我交流。

接下来,我们继续看另一个AFURLSessionManagerTaskDelegate类。这个类的目的是用来针对每一个task对象进行具体操作和响应的,如其名为代理者,正是设计模式中的代理模式的实际事例,我们看下其声明:

// 此类遵守NSURLSession相关协议,方便外部直接调用协议方法
@interface AFURLSessionManagerTaskDelegate : NSObject <NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>
// 使用task对象初始化,task用于progress的回调操作
- (instancetype)initWithTask:(NSURLSessionTask *)task;
// 弱引用manager对象
@property (nonatomic, weak) AFURLSessionManager *manager;
// 用来保存接收到的数据对象
@property (nonatomic, strong) NSMutableData *mutableData;
// 上传进度
@property (nonatomic, strong) NSProgress *uploadProgress;
// 下载进度
@property (nonatomic, strong) NSProgress *downloadProgress;
// 下载存储地址
@property (nonatomic, copy) NSURL *downloadFileURL;
#if AF_CAN_INCLUDE_SESSION_TASK_METRICS
// 任务数据采集
@property (nonatomic, strong) NSURLSessionTaskMetrics *sessionTaskMetrics AF_API_AVAILABLE(ios(10), macosx(10.12), watchos(3), tvos(10));
#endif
// 各种回调
@property (nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading;
@property (nonatomic, copy) AFURLSessionTaskProgressBlock uploadProgressBlock;
@property (nonatomic, copy) AFURLSessionTaskProgressBlock downloadProgressBlock;
@property (nonatomic, copy) AFURLSessionTaskCompletionHandler completionHandler;
@end

声明类中的属性都比较直观,我们看下具体的实现逻辑:

- (instancetype)initWithTask:(NSURLSessionTask *)task {
    ...
    _mutableData = [NSMutableData data];
    _uploadProgress = [[NSProgress alloc] initWithParent:nil userInfo:nil];
    _downloadProgress = [[NSProgress alloc] initWithParent:nil userInfo:nil];
    __weak __typeof__(task) weakTask = task;
    for (NSProgress *progress in @[ _uploadProgress, _downloadProgress ])
    {
      // progress的相关配置省略掉
       ...
        // 对progress变化进行监控
        [progress addObserver:self
                   forKeyPath:NSStringFromSelector(@selector(fractionCompleted))
                      options:NSKeyValueObservingOptionNew
                      context:NULL];
    }
    return self;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    // 进度发生变化时,通过block通知外部调用方
    if ([object isEqual:self.downloadProgress]) {
        if (self.downloadProgressBlock) {
            self.downloadProgressBlock(object);
        }
    }
    ...
}

// URLSession请求完成回调
- (void)URLSession:(__unused NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    // 优先取身份挑战的error
    error = objc_getAssociatedObject(task, AuthenticationChallengeErrorKey) ?: error;
    __strong AFURLSessionManager *manager = self.manager;
    __block id responseObject = nil;
    NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
    userInfo[AFNetworkingTaskDidCompleteResponseSerializerKey] = manager.responseSerializer;
    // 下载数据完成时会copy为不可变对象,优化内存的写法
    NSData *data = nil;
    if (self.mutableData) {
        data = [self.mutableData copy];
        self.mutableData = nil;
    }
    ...
    // 使用downloadTask对象时,会有file url;使用dataTask对象下载时会有data。
    if (self.downloadFileURL) {
        userInfo[AFNetworkingTaskDidCompleteAssetPathKey] = self.downloadFileURL;
    } else if (data) {
        userInfo[AFNetworkingTaskDidCompleteResponseDataKey] = data;
    }
    
    if (error) {
        ...
    } else {
        dispatch_async(url_session_manager_processing_queue(), ^{
            NSError *serializationError = nil;
            // 通过session manager中的response序列化器进行数据序列化
            responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:data error:&serializationError];
            // 如果是downloadTask下载任务则使用文件路径
            if (self.downloadFileURL) {
                responseObject = self.downloadFileURL;
            }
            if (responseObject) {
                userInfo[AFNetworkingTaskDidCompleteSerializedResponseKey] = responseObject;
            }
            if (serializationError) {
                userInfo[AFNetworkingTaskDidCompleteErrorKey] = serializationError;
            }
            dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{ 
                // 请求成功后,在指定的group和queue中进行回调
                if (self.completionHandler) {
                    self.completionHandler(task.response, responseObject, serializationError);
                }
                // 主线程发送通知,外部同样是主线程接收通知
                dispatch_async(dispatch_get_main_queue(), ^{
                    [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];
                });
            });
        });
    }
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
    self.downloadFileURL = nil;
    // 如果存在task自身的设置,则使用自身的设置来获取file url。
    // 可以看到delegate对象中存在downloadTaskDidFinishDownloading回调,session manager中同样存在
    // 里面有很多这种写法,既可以让session manager统一设置,也可以让delegate自行设置
    if (self.downloadTaskDidFinishDownloading) {
        self.downloadFileURL = self.downloadTaskDidFinishDownloading(session, downloadTask, location);
        if (self.downloadFileURL) {
            NSError *fileManagerError = nil;
            if (![[NSFileManager defaultManager] moveItemAtURL:location toURL:self.downloadFileURL error:&fileManagerError]) {
                [[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidFailToMoveFileNotification object:downloadTask userInfo:fileManagerError.userInfo];
            } else {
                [[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidMoveFileSuccessfullyNotification object:downloadTask userInfo:nil];
            }
        }
    }
}

现在两个简单的类看完了,这里一定要想清楚AFURLSessionManagerTaskDelegate的作用是什么。接下来看下主体类AFURLSessionManager的实现:

/* 隐式声明 */
@interface AFURLSessionManager ()
// session配置对象
@property (readwrite, nonatomic, strong) NSURLSessionConfiguration *sessionConfiguration;
// session delegate回调队列
@property (readwrite, nonatomic, strong) NSOperationQueue *operationQueue;
// manager持有的session对象
@property (readwrite, nonatomic, strong) NSURLSession *session;
// 用来管理每一个task对应的delegate,key为task.taskIdentifier,value为delegate对象
@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableTaskDelegatesKeyedByTaskIdentifier;
// 当前session的地址
@property (readonly, nonatomic, copy) NSString *taskDescriptionForSessionTasks;
// mutableTaskDelegatesKeyedByTaskIdentifier的安全锁
@property (readwrite, nonatomic, strong) NSLock *lock;
...
@end

/* 实现 */
- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
    ...
    if (!configuration) {
        configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    }
    self.sessionConfiguration = configuration;
    // 串行队列
    self.operationQueue = [[NSOperationQueue alloc] init];
    self.operationQueue.maxConcurrentOperationCount = 1;
    // 默认json格式的response序列化器
    self.responseSerializer = [AFJSONResponseSerializer serializer];
    // 安全策略,默认none
    self.securityPolicy = [AFSecurityPolicy defaultPolicy];
    
#if !TARGET_OS_WATCH
    self.reachabilityManager = [AFNetworkReachabilityManager sharedManager];
#endif
    
    self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];
    
    self.lock = [[NSLock alloc] init];
    self.lock.name = AFURLSessionManagerLockName;
    
    // 在初始化时调用该方法的目的防止某些情况下,例如切换后台,导致一些未完成的task丢失导致崩溃
    [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
        for (NSURLSessionDataTask *task in dataTasks) {
            [self addDelegateForDataTask:task uploadProgress:nil downloadProgress:nil completionHandler:nil];
        }
        
        for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
            [self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil];
        }
        
        for (NSURLSessionDownloadTask *downloadTask in downloadTasks) {
            [self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil];
        }
    }];
    
    return self;
}

AFHTTPSessionManager

这个类就相对简单了,提供的都是发起HTTP请求的一些便利方法,只需要大致一看即可:

// 使用NS_DESIGNATED_INITIALIZER修饰的指定初始化器,其他init方法可以当做便捷初始化器
- (instancetype)initWithBaseURL:(nullable NSURL *)url 
           sessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER;

// GET请求的快捷方法
- (nullable NSURLSessionDataTask *)GET:(NSString *)URLString
                            parameters:(nullable id)parameters
                               headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                              progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress
                               success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                               failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
// POST请求上传数据的快捷方法
// 在constructingBodyWithBlock回调中的formData中添加需要上传的数据,上文讲解过
- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
                             parameters:(nullable id)parameters
                                headers:(nullable NSDictionary <NSString *, NSString *> *)headers
              constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
                               progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
// 通用方法
- (nullable NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
                                                URLString:(NSString *)URLString
                                               parameters:(nullable id)parameters
                                                  headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                                           uploadProgress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
                                         downloadProgress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress
                                                  success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                                  failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

很简单对吧,我们浏览一遍实现文件:

- (instancetype)initWithBaseURL:(NSURL *)url
           sessionConfiguration:(NSURLSessionConfiguration *)configuration {
    ...
    // 此写法是为了保证url拼接不出错,可以看以下注释:
    /*
        NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"];
        [NSURL URLWithString:@"foo" relativeToURL:baseURL];                  // http://example.com/v1/foo
        [NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL];          // http://example.com/v1/foo?bar=baz
        [NSURL URLWithString:@"/foo" relativeToURL:baseURL];                 // http://example.com/foo
        [NSURL URLWithString:@"foo/" relativeToURL:baseURL];                 // http://example.com/v1/foo
        [NSURL URLWithString:@"/foo/" relativeToURL:baseURL];                // http://example.com/foo/
        [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/
    */
    if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) {
        url = [url URLByAppendingPathComponent:@""];
    }
    self.baseURL = url;
    // 默认HTTP请求序列化器和JSON响应序列化器
    self.requestSerializer = [AFHTTPRequestSerializer serializer];
    self.responseSerializer = [AFJSONResponseSerializer serializer];
    return self;
}

- (NSURLSessionDataTask *)GET:(NSString *)URLString
                   parameters:(nullable id)parameters
                      headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                     progress:(nullable void (^)(NSProgress * _Nonnull))downloadProgress
                      success:(nullable void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
                      failure:(nullable void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure {
    NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET" URLString:URLString parameters:parameters headers:headers uploadProgress:nil downloadProgress:downloadProgress success:success failure:failure];
    [dataTask resume];
    return dataTask;
}


- (NSURLSessionDataTask *)POST:(NSString *)URLString
                    parameters:(nullable id)parameters
                       headers:(nullable NSDictionary<NSString *,NSString *> *)headers
     constructingBodyWithBlock:(nullable void (^)(id<AFMultipartFormData> _Nonnull))block
                      progress:(nullable void (^)(NSProgress * _Nonnull))uploadProgress
                       success:(nullable void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure {
    NSError *serializationError = nil;
    // 上传数据需要通过请求序列化器来初始化request
    NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError];
    // 设置请求头
    for (NSString *headerField in headers.keyEnumerator) {
        [request setValue:headers[headerField] forHTTPHeaderField:headerField];
    }
    if (serializationError) {
        if (failure) {
            dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                failure(nil, serializationError);
            });
        }
        return nil;
    }
    // 调用父类的upload request方法进行上传
    __block NSURLSessionDataTask *task = [self uploadTaskWithStreamedRequest:request progress:uploadProgress completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
        if (error) {
            if (failure) {
                failure(task, error);
            }
        } else {
            if (success) {
                success(task, responseObject);
            }
        }
    }];
    [task resume];
    return task;
}

- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
                                       URLString:(NSString *)URLString
                                      parameters:(nullable id)parameters
                                         headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                                  uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress
                                downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
                                         success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                         failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure {
    NSError *serializationError = nil;
    // 对于非上传数据的请求,直接调用request序列化器生成普通的request
    NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
    for (NSString *headerField in headers.keyEnumerator) {
        [request setValue:headers[headerField] forHTTPHeaderField:headerField];
    }
    if (serializationError) {
        if (failure) {
            dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                failure(nil, serializationError);
            });
        }

        return nil;
    }

    __block NSURLSessionDataTask *dataTask = nil;
    // 调用父类来生成普通的dataTask
    dataTask = [self dataTaskWithRequest:request
                          uploadProgress:uploadProgress
                        downloadProgress:downloadProgress
                       completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
        ...
    }];
    return dataTask;
}

AFHTTPSessionManager这个类非常的简单,却是我们使用中最直接用到的类,其内部包括了其他几个类的实例属性,属于大一统的类。