Alamofire5.0源碼分析(一)

前言

Alamofire在5.0進(jìn)行一次重構(gòu),現(xiàn)在還未正式發(fā)布,下面的分析都基于5.0.0-rc.3版本

問(wèn)題

在進(jìn)入正文之前,先看下下面這幾個(gè)問(wèn)題,希望你看完這篇文章,能回答以下問(wèn)題?

  1. Session,SessionDelegate,Request它們之間的關(guān)系?
let urlString = "https://api.apiopen.top/getJoke?page=1&count=2&type=text"
let request = AF.request(urlString).responseJSON { (resp) in
    print(resp)
}
//假設(shè)請(qǐng)求3秒之后就回來(lái)了
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
    request.responseJSON { (resp) in
        print(resp)
    }
}
  1. 都知道Alamofire是對(duì)URLSession的封裝,上面那段代碼,DataTask是什么時(shí)候創(chuàng)建的,又是什么發(fā)送的?
  2. 在請(qǐng)求回來(lái)之后,再多次設(shè)置響應(yīng),是否能進(jìn)行回調(diào)?
  3. responseJSON里面都做了些什么事?

Alamofire中主要的類或協(xié)議圖

image

Session,SessionDelegate,Request,RequestDelegate主要屬性介紹

Session屬性:
  1. let session: URLSession,系統(tǒng)的URLSession,用于創(chuàng)建task
  2. let delegate: SessionDelegate,session的代理,用于處理請(qǐng)求的各種回調(diào)
  3. let startRequestsImmediately: Bool,是否立即發(fā)出請(qǐng)求
  4. let rootQueue: DispatchQueue,內(nèi)部的回調(diào)和狀態(tài)更新所處的隊(duì)列,必須是串行隊(duì)列
  5. let requestQueue: DispatchQueue,創(chuàng)建Request所在的隊(duì)列,默認(rèn)是target為rootQueue的串行隊(duì)列
  6. let serializationQueue: DispatchQueue,反序列化Response數(shù)據(jù)時(shí)所在的隊(duì)列,默認(rèn)是target為rootQueue的串行隊(duì)列
  7. let interceptor: RequestInterceptor?,request攔截器,是RequestAdapter和RequestRetrier的合并,用于在發(fā)送請(qǐng)求之前修改Request和請(qǐng)求失敗之后的重試策略
  8. let serverTrustManager: ServerTrustManager?,安全認(rèn)證管理者
  9. let redirectHandler: RedirectHandler?,重定向的回調(diào)
  10. let cachedResponseHandler: CachedResponseHandler?,緩存的回來(lái)
  11. let eventMonitor: CompositeEventMonitor,事件監(jiān)聽(tīng)器
  12. var requestTaskMap:RequestTaskMap,用于存放task、request以及task的狀態(tài)
  13. var activeRequests:Set<Request> = [],用于所有活躍的request
SessionDelegate屬性:
  1. private let fileManager: FileManager,用于下載的回調(diào)里,處理文件
  2. weak var stateProvider: SessionStateProvider? ,用于在URLSessionDelegate獲取request信息以及回調(diào)給外面狀態(tài)
  3. var eventMonitor: EventMonitor?,在各種回調(diào)里,調(diào)用事件監(jiān)聽(tīng)器對(duì)應(yīng)的方法,讓外界處理
SessionStateProvider協(xié)議定義的方法:
  1. var serverTrustManager: ServerTrustManager? { get }獲取安全認(rèn)證管理者
  2. var redirectHandler: RedirectHandler? { get }獲取重定向的處理者
  3. var cachedResponseHandler: CachedResponseHandler? { get }獲取緩存響應(yīng)的處理者
  4. func request(for task: URLSessionTask) -> Request?通過(guò)task獲取Request
  5. func didGatherMetricsForTask(_ task: URLSessionTask)收集到性能指標(biāo)之后的回調(diào)
  6. func didCompleteTask(_ task: URLSessionTask)請(qǐng)求完成的回調(diào)
  7. func credential(for task: URLSessionTask, in protectionSpace: URLProtectionSpace) -> URLCredential?獲取身份驗(yàn)證的證書(shū)
  8. func cancelRequestsForSessionInvalidation(with error: Error?),URLSession無(wú)效的回調(diào)
Request屬性:
  1. let underlyingQueue: DispatchQueue,內(nèi)部回調(diào)的異步串行隊(duì)列
  2. let serializationQueue: DispatchQueue,序列化所在的隊(duì)列,同Session
  3. let eventMonitor: EventMonitor?,事件監(jiān)聽(tīng)器,同Session
  4. let interceptor: RequestInterceptor?,request攔截器,同Session
  5. weak var delegate: RequestDelegate?,requestDelegate
  6. protectedMutableState: Protector<MutableState>,存放著request的各種信息
    1. state狀態(tài)
    2. uploadProgressHandler上傳的進(jìn)度回調(diào)
    3. downloadProgressHandler下載的進(jìn)度回調(diào)
    4. redirectHandler重定向的回調(diào)
    5. cachedResponseHandler緩存的回調(diào)
    6. cURLHandler,curl的回調(diào)
    7. responseSerializers,響應(yīng)序列化的集合
    8. responseSerializerCompletions,響應(yīng)序列化回調(diào)的集合
    9. requests,當(dāng)前請(qǐng)求所有的request
    10. tasks,當(dāng)前請(qǐng)求所有的task
    11. metrics,當(dāng)前請(qǐng)求所有的指標(biāo)
    12. retryCount,已經(jīng)重試的次數(shù)
    13. 錯(cuò)誤信息
  7. 其他屬性都間接或這屆的依賴于protectedMutableState
RequestDelegate協(xié)議定義的方法:
  1. var sessionConfiguration: URLSessionConfiguration { get },獲取Session配置
  2. var startImmediately: Bool { get },是否立即發(fā)送請(qǐng)求
  3. func cleanup(after request: Request),此次請(qǐng)求已結(jié)束,清除此次請(qǐng)求
  4. func retryResult(for request: Request, dueTo error: AFError, completion: @escaping (RetryResult) -> Void),詢問(wèn)代理是否需要重試
  5. func retryRequest(_ request: Request, withDelay timeDelay: TimeInterval?),告訴代理在多久之后重試

Session,SessionDelegate,Request之間的關(guān)系

image
  1. Session創(chuàng)建之后會(huì)創(chuàng)建URLSession,此時(shí)Session.delegate和URLSession.delegate都指向SessionDelegate的實(shí)例
  2. Session.delegate指向SessionDelegate是為了持有它,不讓他釋放,URLSession.delegate指向它,是讓它執(zhí)行URLSession以及URLSessionTask的各種回調(diào)
  3. SessionDelegate.stateProvider會(huì)指向Session
  4. 當(dāng)調(diào)用Session.request方法之后,會(huì)創(chuàng)建Request,并把Request放入Session.activeRequests中
  5. Request.delegate會(huì)指向Session

Request的創(chuàng)建流程圖

image

根據(jù)此流程圖回答上面的問(wèn)題

  1. dataTask是在Session.didCreateURLRequest中創(chuàng)建的,由于創(chuàng)建完Request,無(wú)論是操作Request還是response函數(shù)內(nèi)部操作都是異步,執(zhí)行順序無(wú)法確定,所以發(fā)送請(qǐng)求有可能在這2個(gè)地方,一是Session.updateStatesForTask,二是在Request.resume函數(shù)中
  2. 在請(qǐng)求回來(lái)之后,再多次設(shè)置響應(yīng),從上面的流程圖可以看出,會(huì)直接調(diào)用回調(diào)
  3. response中除了做了流程圖內(nèi)的事之外,在執(zhí)行回調(diào)之前,會(huì)先把data反序列化對(duì)應(yīng)的格式,若序列化失敗,會(huì)調(diào)用代理來(lái)詢問(wèn)是否需要重試,若反序列化成功,則調(diào)用回調(diào)

Request請(qǐng)求完成之后到調(diào)用響應(yīng)回調(diào)的流程圖

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容