Alamofire源码导读一:框架
源码架构

Alamofire 的源码包括 Core、Extensions、Features、Supporting Files。其中主要逻辑在 Core里。
包括构造请求,发起请求,处理回调等。
Core 的架构

Core 中主要有 SessionManager、SessionDelegate、Request和 TaskDelegate 这些类。
SessionManager
是一切的起点,它持有一个 URLSession,这个 URLSession 管理着发出的所有网络请求。
它提供了各种方法来生成 Request,也就是网络请求。
它持有一个 SessionDelegate,在其中处理所有系统的网络回调。
SessionDelegate
继承自NSObject
以字典方式持有了所有 Request,key 是URLSessionTask 的 taskIdentifier。并提供了一个方法,可以根据 URLSessionTask 返回对应的 Request。
处理 SessionManager 中的 URLSession 的所有回调。
它提供了各种闭包,对应相应的delegate方法,可以用来配置如何处理网络的回调。外部设置的回调总是优先于默认实现。
/// Overrides default behavior for URLSessionTaskDelegate method `urlSession(_:task:willPerformHTTPRedirection:newRequest:completionHandler:)`.
open var taskWillPerformHTTPRedirection: ((URLSession, URLSessionTask, HTTPURLResponse, URLRequest) -> URLRequest?)?
/// Overrides all behavior for URLSessionTaskDelegate method `urlSession(_:task:willPerformHTTPRedirection:newRequest:completionHandler:)` and
/// requires the caller to call the `completionHandler`.
open var taskWillPerformHTTPRedirectionWithCompletion: ((URLSession, URLSessionTask, HTTPURLResponse, URLRequest, @escaping (URLRequest?) -> Void) -> Void)?
比如它定义了两个闭包,来处理重定向问题。在回调中,如果对于的闭包不是空,就会执行这个闭包。
open func urlSession(
    _ session: URLSession,
    task: URLSessionTask,
    willPerformHTTPRedirection response: HTTPURLResponse,
    newRequest request: URLRequest,
    completionHandler: @escaping (URLRequest?) -> Void)
{
    guard taskWillPerformHTTPRedirectionWithCompletion == nil else {
        taskWillPerformHTTPRedirectionWithCompletion?(session, task, response, request, completionHandler)
        return
    }
    var redirectRequest: URLRequest? = request
    if let taskWillPerformHTTPRedirection = taskWillPerformHTTPRedirection {
        redirectRequest = taskWillPerformHTTPRedirection(session, task, response, request)
    }
    completionHandler(redirectRequest)
}
Request
对网络请求的封装,对应一个 underlying 的 URLSessionTask。
不同类型的网络请求,有不同的子类,比如DataRequest对应URLSessionDataTask。
强持有一个 TaskDelegate。
TaskDelegate
用来实现对应Request的协议。
内部有一个串行的OperationQueue,在请求结束后处理任务。
比如常见的responseJSON 函数,其回调就是在这个 OperationQueue 中被执行。
各个类之间的引用关系

一图胜千言,在请求过程中,持有关系是SessionManager -> SessionDelegate -> Request -> TaskDelegate。
在网络返回之后,在SessionDelegate 会清理掉对应的Request。

因此,Request 不会被SessionDelegate持有了,但是必须被另一个对象持有。否则,TaskDelegate会被释放,其OperationQueue  中的任务不会被执行。

Request 持有 SessionDelegate

如上图,Request 持有一个 URLSession,而这个URLSession 的 delegate 正是 SessionDelegate。
因此有一个圈,SessionDelegate->Request->URLSession->SessionDelegate。
在网络完成以后,SessionDelegate 会释放对应的Request,从而打破这个循环引用。
附一个URLSession的层级图

Alamofire源码导读一:框架的更多相关文章
- Alamofire源码导读三:返回的处理逻辑
		
 以DataRequest 为例子. 最简单的返回 URLSession 有一个方法,可以构建 URLSessionDataTask func dataTask(with url: URL, com ...
 - Alamofire源码导读五:错误表示
		
AFError is the error type returned by Alamofire. It encompasses a few different types of errors, eac ...
 - Alamofire源码导读四:统计信息
		
 时间顺序如上图: self.latency = initialResponseTime - requestStartTime self.requestDuration = requestCompl ...
 - Alamofire源码导读二:发起请求及内部加锁的逻辑
		
以创建一个 DataRequest 为例子  发起请求 创建 SessionManager 顺带也创建了一个 SessionDelegate 持有一个urlSession,持有一个串行的 Dispa ...
 - iOS开发之Alamofire源码深度解析
		
今天博客中的Alamofire源码的版本是以现在最新的3.4版本为例.上篇博客系统的对NSURLSession相关的东西进行了详细的解析,详情请看<详解NSURLSession>,为了就是 ...
 - iOS开发之Alamofire源码解析前奏--NSURLSession全家桶
		
今天博客的主题不是Alamofire, 而是iOS网络编程中经常使用的NSURLSession.如果你想看权威的NSURLSession的东西,那么就得去苹果官方的开发中心去看了,虽然是英文的,但是结 ...
 - Alamofire源码解读系列(二)之错误处理(AFError)
		
本篇主要讲解Alamofire中错误的处理机制 前言 在开发中,往往最容易被忽略的内容就是对错误的处理.有经验的开发者,能够对自己写的每行代码负责,而且非常清楚自己写的代码在什么时候会出现异常,这样就 ...
 - Alamofire源码解读系列(六)之Task代理(TaskDelegate)
		
本篇介绍Task代理(TaskDelegate.swift) 前言 我相信可能有80%的同学使用AFNetworking或者Alamofire处理网络事件,并且这两个框架都提供了丰富的功能,我也相信很 ...
 - Alamofire源码解读系列(九)之响应封装(Response)
		
本篇主要带来Alamofire中Response的解读 前言 在每篇文章的前言部分,我都会把我认为的本篇最重要的内容提前讲一下.我更想同大家分享这些顶级框架在设计和编码层次究竟有哪些过人的地方?当然, ...
 
随机推荐
- java bulid path  和 WEB-INF/lib 下jar  包区别
			
用Java Build Path导入包和把包复制到lib下是有区别的,它俩其实不会冲突,也没有什么关系的, Java Build Path是我们编译需要的包, 导入到lib下是程序运行时需要的包 , ...
 - 2018.09.09 codeforces280C. Game on Tree(期望dp)
			
传送门 期望dp经典题. 显然只需要算出每个点被染黑的期望步数. 点i被染黑的期望是1/(1到i这条链上的节点数)" role="presentation" style= ...
 - 2018.07.06 BZOJ1208: HNOI2004宠物收养所(非旋treap)
			
1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec Memory Limit: 162 MB Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收 ...
 - Django入门指南-第10章:Django Admin 介绍(完结)
			
在浏览器中打开该URL:http://127.0.0.1:8000/admin/ 我们可以检查一切是否正常,打开URL http://127.0.0.1:8000 我们首先创建一个管理员帐户: pyt ...
 - C语言之控制台读取上下左右方向键指令
			
首先,可以检测任何按键键值 // 首先,检测任何按键的代码 #include<stdio.h> #include<conio.h> int main() { char ch; ...
 - 用jQ实现一个简易计算器
			
HTML和CSS结构: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...
 - (KMP 最大表示最小表示)String Problem -- hdu-- 3374
			
http://acm.hdu.edu.cn/showproblem.php?pid=3374 String Problem Time Limit: 2000/1000 MS (Java/Others) ...
 - 聚合函数、group by
			
聚合函数: sql语言中一种特殊的函数:聚合函数,SUM, COUNT, MAX, MIN, AVG等.这些函数和其它函数的根本区别就是它们一般作用在多条记录上.SELECT SUM(populati ...
 - hdu 4996 1~n排列LIS值为k个数
			
http://acm.hdu.edu.cn/showproblem.php?pid=4996 直接贴bc题解 按数字1-N的顺序依次枚举添加的数字,用2N的状态保存在那个min数组中的数字,每次新添加 ...
 - RelativeLayout中最底的View一个View.layout_marginBottom无效
			
处理一个Dialog,发现RelativeLayout布局下最后一个View的layout_marginBottom会失效. 效果图见: 解决方法为: 在最底或最右的组件后面再加个View吧... 这 ...