1. 程式人生 > >Alamofire原始碼導讀一:框架

Alamofire原始碼導讀一:框架

原始碼架構

Alamofire 的原始碼包括 CoreExtensionsFeaturesSupporting Files。其中主要邏輯在 Core裡。
包括構造請求,發起請求,處理回撥等。

Core 的架構

Alamofire1

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的層級圖

sessiondelegates