AFNetworking 3.0 源码阅读笔记(二)

原文链接:http://itangqi.me/2016/05/06/the-notes-of-learning-afnetworking-two/

前言

首先,我们来看一下 AFNetworking 框架中主要涉及到了哪些类:

NSURLSession

  • AFURLSessionManager
  • AFHTTPSessionManager

序列化

  • AFURLRequestSerialization
  • AFURLResponseSerialization

附加功能

  • AFSecurityPolicy
  • AFNetworkReachabilityManager

下面,通过一张图来直观地感受下 AF 架构的设计:


AFHTTPSessionManager

AFHTTPSessionManager is a subclass of AFURLSessionManager with convenience methods for making HTTP requests. When a baseURL is provided, requests made with the GET / POST / et al. convenience methods can be made with relative paths.

一句话总结:AFHTTPSessionManager 继承于 AFURLSessionManager,并提供了方便的 HTTP 请求方法。

下面,我们通过一段实际代码来感受下:

1
2
3
4
5
6
AFHTTPSessionManager *sessionManager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:@"https://api.app.net/"]];
[sessionManager GET:@"stream/0/posts/stream/global" parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
    NSLog(@"请求成功---%@", responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求失败---%@", error);
}];

通过上面短短几行代码,我们便完成了 GET 请求,有木有很简单!现在是不是很想知道其背后蕴藏的玄机呢?别急,下面就让我们一起来探一探究竟。


调用栈

initWithBaseURL:

首先,我们来探一探 AFHTTPSessionManager 初始化方法 - initWithBaseURL: 的调用栈:

1
AFHTTPSessionManager *sessionManager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:@"https://api.app.net/"]];

我们一路「Command + 左键」,可以归纳出如下结果:

1
2
3
4
5
6
7
8
9
- [AFHTTPSessionManager initWithBaseURL:]
    - [AFHTTPSessionManager initWithBaseURL:sessionConfiguration:]
        - [AFURLSessionManager initWithSessionConfiguration:]
            - [NSURLSession sessionWithConfiguration:delegate:delegateQueue:]
            - [AFJSONResponseSerializer serializer] // 负责序列化响应
            - [AFSecurityPolicy defaultPolicy] // 负责身份认证
            - [AFNetworkReachabilityManager sharedManager] // 查看网络连接情况
        - [AFHTTPRequestSerializer serializer] // 负责序列化请求
        - [AFJSONResponseSerializer serializer] // 负责序列化响应

从这个初始化方法的调用栈,我们可以非常清晰地了解这个框架的结构:

  • 其中 AFURLSessionManagerAFHTTPSessionManager 的父类
  • AFURLSessionManager 负责生成 NSURLSession 的实例,管理 AFSecurityPolicyAFNetworkReachabilityManager,来保证请求的安全和查看网络连接情况,它有一个 AFJSONResponseSerializer 的实例来序列化 HTTP 响应
  • AFHTTPSessionManager 有着自己的 AFHTTPRequestSerializerAFJSONResponseSerializer 来管理请求和响应的序列化,同时依赖父类提供的接口保证安全、监控网络状态,实现发出 HTTP 请求这一核心功能
baseURL

关于 baseURL 一开始我是有点迷糊的,不过源代码中有如下注释:

For HTTP convenience methods, the request serializer constructs URLs from the path relative to the -baseURL, using NSURL +URLWithString:relativeToURL:, when provided. If baseURL is nil, path needs to resolve to a valid NSURL object using NSURL +URLWithString:.

并举例进行了说明:

1
2
3
4
5
6
7
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/

所以,baseURL 为访问的基路径如:https://api.app.net/, path 是跟在基路径之后的部分路径,如:stream/0/posts/stream/global(因为 AFNetworking 的访问方式才这样划分)。

GET:parameters:process:success:failure:

初始化方法很好地揭示了 AFNetworking 整个框架的架构,接下来我们要通过分析另一个方法 - GET:parameters:process:success:failure: 的调用栈,看一下 HTTP 请求是如何发出的:

1
2
3
4
5
6
7
8
9
- [AFHTTPSessionManager GET:parameters:process:success:failure:]
    - [AFHTTPSessionManager dataTaskWithHTTPMethod:parameters:uploadProgress:downloadProgress:success:failure:] // 返回 NSURLSessionDataTask #1
        - [AFHTTPRequestSerializer requestWithMethod:URLString:parameters:error:] // 返回 NSMutableURLRequest
        - [AFURLSessionManager dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:] // 返回 NSURLSessionDataTask #2
            - [NSURLSession dataTaskWithRequest:] // 返回 NSURLSessionDataTask #3
            - [AFURLSessionManager addDelegateForDataTask:uploadProgress:downloadProgress:completionHandler:]
                - [AFURLSessionManagerTaskDelegate init]
                - [AFURLSessionManager setDelegate:forTask:]
    - [NSURLSessionDataTask resume]

在这里 #1 #2 #3 处返回的是同一个 data task,我们可以看到,在 #3 处调用的方法 - [NSURLSession dataTaskWithRequest:] 和只使用 NSURLSession 发出 HTTP 请求时调用的方法 - [NSURLSession dataTaskWithRequest:completionHandler:] 差不多。在这个地方返回 data task 之后,我们再调用 - resume 方法执行请求,并在某些事件执行时通知代理 AFURLSessionManagerTaskDelegate

我们在第一篇文章中已经说明过,AFNetworking 3.0 既是在 NSURLSession 之上的高度封装,并提供更加简洁易用的 API。从调用栈的结果来看,将使我们的理解更加清晰。


循环引用

关于在使用 AFNetworking 的过程中出现循环引用的问题,我并没有在实际开发中遇到过(其实我丫的根本就没写过几行代码好嘛( TДT)),我是在浏览相关文章时发现这个问题的,所以在此提及一下:


参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值