博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AFN3.0源码解析
阅读量:6280 次
发布时间:2019-06-22

本文共 14910 字,大约阅读时间需要 49 分钟。

目录结构

  1. NSURLSession

    这个目录是封装了http请求需要的代码,其中AFURLSessionManager类主要处理http请求,AFHTTPSessionManager类是对其进行封装留给用户调用的上层接口。比如我们平时的get,post请求就要用到该类,也是本文要分析的重点。

  2. Reachability

    这个目录是判断网络状态的

  3. Security

    https请求

  4. Serialization

    http请求和相应的配置

  5. UIKit

    分类

post请求过程

第一步:用户创建单例

+ (instancetype)shareManager{    static dispatch_once_t token;    static HttpClientManager *instance = nil;    _dispatch_once(&token, ^{        instance = [[self alloc] init];        [instance initSession];    });    return instance;}- (void)initSession{    _sessionManger = [AFHTTPSessionManager manager];    _sessionManger.requestSerializer = [AFJSONRequestSerializer serializer];//请求配置    AFJSONResponseSerializer *response = [AFJSONResponseSerializer serializer];//相应配置    response.removesKeysWithNullValues = YES;//当出现null值时候移除该键值对    _sessionManger.responseSerializer =  response;    _sessionManger.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/json", @"text/plain", @"text/html", nil];//相应配置    _baseUrl = @"http:xxxxx/";//协议+域名+端口号(请求前缀)}复制代码

[AFHTTPSessionManager manager]查看源代码发现接下来调用一下代码

//1.(AFHTTPSessionManager类)+ (instancetype)manager {    return [[[self class] alloc] initWithBaseURL:nil];}//2.(AFHTTPSessionManager类)- (instancetype)initWithBaseURL:(NSURL *)url {    return [self initWithBaseURL:url sessionConfiguration:nil];}//3.(AFHTTPSessionManager类)- (instancetype)initWithBaseURL:(NSURL *)url           sessionConfiguration:(NSURLSessionConfiguration *)configuration{    self = [super initWithSessionConfiguration:configuration];//分析父类    if (!self) {        return nil;    }    // Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected    if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) {        url = [url URLByAppendingPathComponent:@""];    }    self.baseURL = url;    self.requestSerializer = [AFHTTPRequestSerializer serializer];    self.responseSerializer = [AFJSONResponseSerializer serializer];    return self;}//4.(AFURLSessionManager类)- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {    self = [super init];    if (!self) {        return nil;    }    if (!configuration) {        configuration = [NSURLSessionConfiguration defaultSessionConfiguration];    }    self.sessionConfiguration = configuration;    self.operationQueue = [[NSOperationQueue alloc] init];    self.operationQueue.maxConcurrentOperationCount = 1;    self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];//注意delegate = self,也就是说网络请求的结果在AFURLSessionManager类里    self.responseSerializer = [AFJSONResponseSerializer serializer];    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;    [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初始化的分析

第二步:用户开始调用post方法

[_sessionManger POST:urlString parameters:dicM progress:nil        success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {            //请求成功        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {            //error包含HTTP请求的错误码,或者NSURLError错误码(-1001,-1009等等)    }];复制代码

查看源代码调用过程如下

1.(AFHTTPSessionManager类)- (NSURLSessionDataTask *)POST:(NSString *)URLString                    parameters:(id)parameters                      progress:(void (^)(NSProgress * _Nonnull))uploadProgress                       success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success                       failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure{    NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure];//分析源代码(回调已经向下传递)    [dataTask resume];    return dataTask;}2.(AFHTTPSessionManager类)- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method                                       URLString:(NSString *)URLString                                      parameters:(id)parameters                                  uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress                                downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress                                         success:(void (^)(NSURLSessionDataTask *, id))success                                         failure:(void (^)(NSURLSessionDataTask *, NSError *))failure{    NSError *serializationError = nil;    NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];//请求配置    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) {                           //回调(最上层的回调要执行那么就必须该completionHandler回调必须执行,也就是说completionHandler回调执行与否决定最上层的回调是否执行。我们只要关心completionHandler回调即可)        if (error) {            if (failure) {                failure(dataTask, error);            }        } else {            if (success) {                success(dataTask, responseObject);            }        }    }];    return dataTask;//返回dataTask}//3.(AFURLSessionManager类)- (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 {    __block NSURLSessionDataTask *dataTask = nil;    url_session_manager_create_task_safely(^{        //创建dataTask        dataTask = [self.session dataTaskWithRequest:request];    });    //addDelegate(completionHandler向下传递),向下分析源代码    [self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];    return dataTask;}//4.(AFURLSessionManager类)- (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTask                uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock              downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock             completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler{    AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] initWithTask:dataTask];    delegate.manager = self;    //将回调保存到AFURLSessionManagerTaskDelegate对象里    delegate.completionHandler = completionHandler;    dataTask.taskDescription = self.taskDescriptionForSessionTasks;    //传入delegate对象,dataTask(向下分析源代码)    [self setDelegate:delegate forTask:dataTask];        delegate.uploadProgressBlock = uploadProgressBlock;    delegate.downloadProgressBlock = downloadProgressBlock;}//5.(AFURLSessionManager类)- (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate            forTask:(NSURLSessionTask *)task{    NSParameterAssert(task);    NSParameterAssert(delegate);    //避免多线程访问mutableTaskDelegatesKeyedByTaskIdentifier字典    [self.lock lock];    //将AFURLSessionManagerTaskDelegate对象存储在    //mutableTaskDelegatesKeyedByTaskIdentifier字典里    //AFURLSessionManagerTaskDelegate对象里边存着回调,现在又将该对象存在字典里。并以task.taskIdentifier为key    self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate;    [self addNotificationObserverForTask:task];    [self.lock unlock];}复制代码

经过以上分析知道最后将回调保存在了mutableTaskDelegatesKeyedByTaskIdentifier这个字典里的AFURLSessionManagerTaskDelegate对象中。

然后经过resume后,开始发起post请求。请求的结果回调在AFURLSessionManager类中(上面初始化代码可知)。

第三步:请求结果回调

找到AFURLSessionManager类下的网络请求结果代理方法

//1. (AFURLSessionManager类)- (void)URLSession:(NSURLSession *)session              task:(NSURLSessionTask *)taskdidCompleteWithError:(NSError *)error{    //获取该task对应的AFURLSessionManagerTaskDelegate对象,实际上就是从字典中取值(分析源代码)    AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task];    // delegate may be nil when completing a task in the background    if (delegate) {        //调用AFURLSessionManagerTaskDelegate对象中的URLSession: task: didCompleteWithError:方法(分析源代码)        [delegate URLSession:session task:task didCompleteWithError:error];        //移除task,实际上是从字典中移除(分析源代码)        [self removeDelegateForTask:task];    }   //完成回调,其实这里我们没用到,所以不会进入    if (self.taskDidComplete) {        self.taskDidComplete(session, task, error);    }}//2.(AFURLSessionManager类)- (AFURLSessionManagerTaskDelegate *)delegateForTask:(NSURLSessionTask *)task {    NSParameterAssert(task);    AFURLSessionManagerTaskDelegate *delegate = nil;    [self.lock lock];    //根据task.taskIdentifier获取字典中的AFURLSessionManagerTaskDelegate对象    delegate = self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)];    [self.lock unlock];    return delegate;}//3. (AFURLSessionManager类)- (void)removeDelegateForTask:(NSURLSessionTask *)task {    NSParameterAssert(task);    [self.lock lock];    [self removeNotificationObserverForTask:task];    //从字典中移除task.taskIdentifier对应的AFURLSessionManagerTaskDelegate对象    [self.mutableTaskDelegatesKeyedByTaskIdentifier removeObjectForKey:@(task.taskIdentifier)];    [self.lock unlock];}//4.(AFURLSessionManagerTaskDelegate类)- (void)URLSession:(__unused NSURLSession *)session              task:(NSURLSessionTask *)taskdidCompleteWithError:(NSError *)error{    __strong AFURLSessionManager *manager = self.manager;    __block id responseObject = nil;        //创建空字典userInfo    __block NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];    //userInfo保存responseSerializer    userInfo[AFNetworkingTaskDidCompleteResponseSerializerKey] = manager.responseSerializer;    //Performance Improvement from #2672    //获取data    NSData *data = nil;    if (self.mutableData) {        data = [self.mutableData copy];        //We no longer need the reference, so nil it out to gain back some memory.        self.mutableData = nil;    }    if (self.downloadFileURL) {        //userInfo保存downloadFileURL        userInfo[AFNetworkingTaskDidCompleteAssetPathKey] = self.downloadFileURL;    } else if (data) {        //userInfo保存data        userInfo[AFNetworkingTaskDidCompleteResponseDataKey] = data;    }    if (error) {        //有错误        //userInfo保存error        userInfo[AFNetworkingTaskDidCompleteErrorKey] = error;        dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{            //如果没有定义队列就在主队列回调            if (self.completionHandler) {                //self是AFURLSessionManagerTaskDelegate对象,经过以上分析,该对象中的completionHandler回调,即可触发上层回调                self.completionHandler(task.response, responseObject, error);            }            dispatch_async(dispatch_get_main_queue(), ^{                //发送通知,将userInfo发出                [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];            });        });    } else {        //请求成功        dispatch_async(url_session_manager_processing_queue(), ^{            //定义serializationError            NSError *serializationError = nil;            //data解析为json对象            responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:data error:&serializationError];            if (self.downloadFileURL) {                //responseObject赋值                responseObject = self.downloadFileURL;            }            if (responseObject) {                //userInfo保存responseObject                userInfo[AFNetworkingTaskDidCompleteSerializedResponseKey] = responseObject;            }            if (serializationError) {                //userInfo保存serializationError                userInfo[AFNetworkingTaskDidCompleteErrorKey] = serializationError;            }            dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{                //如果没有定义回调队列,就在主队列回调                if (self.completionHandler) {                    //self是AFURLSessionManagerTaskDelegate对象,经过以上分析,该对象中的completionHandler回调,即可触发上层回调                    self.completionHandler(task.response, responseObject, serializationError);                }                dispatch_async(dispatch_get_main_queue(), ^{                    //发送通知,将userInfo发出                    [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];                });            });        });    }}复制代码

AFN请求过程梳理

首先我们是初始化了AFHTTPSessionManager类(往往创建单例)初始化时候指定请求回调的代理是父类(AFURLSessionManager)。之后当我们发出一个请求后,先创建一个AFURLSessionManagerTaskDelegate对象来保存请求结果回调。并把该对象放到一个全局字典中来保存(以task.taskIdentifier为key),再启动请求。当AFURLSessionManager类收到了请求结果后根据task.taskIdentifier从全局字典中取出当前请求的AFURLSessionManagerTaskDelegate对象。然后调用AFURLSessionManagerTaskDelegate的对象方法处理请求,完成回调。之后再从全局字典中移除该AFURLSessionManagerTaskDelegate对象。

AFN是怎样来解决循环引用的

首先我们用AFN时候往往是用单例,因此调用类不会直接持有该AFHTTPSessionManager对象。

该AFHTTPSessionManager对象持有block,该AFHTTPSessionManager对象持有全局字典,该全局字典持有AFURLSessionManagerTaskDelegate对象,该AFURLSessionManagerTaskDelegate对象持有block,这是一个循环引用。

当AFURLSessionManagerTaskDelegate对象block进行回调后,从全局字典中移除该对象。从而打破引用环。

转载于:https://juejin.im/post/5cfdae87f265da1b9253cea3

你可能感兴趣的文章
Javascript 中的 Array 操作
查看>>
java中包容易出现的错误及权限问题
查看>>
AngularJS之初级Route【一】(六)
查看>>
服务器硬件问题整理的一点总结
查看>>
SAP S/4HANA Cloud: Revolutionizing the Next Generation of Cloud ERP
查看>>
Mellanox公司计划利用系统芯片提升存储产品速度
查看>>
白帽子守护网络安全,高薪酬成大学生就业首选!
查看>>
ARM想将芯片装进人类大脑 降低能耗是一大挑战
查看>>
Oracle数据库的备份方法
查看>>
Selenium 自动登录考勤系统
查看>>
关于如何以编程的方式执行TestNG
查看>>
智能照明造福千家万户 家居智能不再是梦
查看>>
物联网如何跳出“看起来很美”?
查看>>
浅谈MySQL 数据库性能优化
查看>>
《UNIX/Linux 系统管理技术手册(第四版)》——1.10 其他的权威文档
查看>>
灵动空间 创享生活
查看>>
《UNIX网络编程 卷1:套接字联网API(第3版)》——8.6 UDP回射客户程序:dg_cli函数...
查看>>
不要将时间浪费到编写完美代码上
查看>>
《第一桶金怎么赚——淘宝开店创业致富一册通》一一第1章 创业梦想,怎样起步...
查看>>
基于容器服务的持续集成与云端交付(三)- 从零搭建持续交付系统
查看>>