Alamofire源码导读一:框架

Posted huahuahu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Alamofire源码导读一:框架相关的知识,希望对你有一定的参考价值。

源码架构

技术分享图片?

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

Core 的架构

技术分享图片?

Core 中主要有 SessionManagerSessionDelegateRequestTaskDelegate 这些类。

SessionManager

是一切的起点,它持有一个 URLSession,这个 URLSession 管理着发出的所有网络请求。
它提供了各种方法来生成 Request,也就是网络请求。
它持有一个 SessionDelegate,在其中处理所有系统的网络回调。

SessionDelegate

继承自NSObject
以字典方式持有了所有 Request,key 是URLSessionTasktaskIdentifier。并提供了一个方法,可以根据 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,而这个URLSessiondelegate 正是 SessionDelegate
因此有一个圈,SessionDelegate->Request->URLSession->SessionDelegate
在网络完成以后,SessionDelegate 会释放对应的Request,从而打破这个循环引用。

附一个URLSession的层级图

技术分享图片?

以上是关于Alamofire源码导读一:框架的主要内容,如果未能解决你的问题,请参考以下文章

Swift - Alamofire源码解析

Swift - Alamofire源码解析

Swift - Alamofire源码解析

Swift - Alamofire源码解析

Alamofire 文件上传出现错误“JSON 文本未以数组或对象开头,并且允许未设置片段的选项”

Apache Druid源码导读--Google guice DI框架