面試總結 - AFN

AFN調用流程分析:

AFHTTPSessionManager: 發起網絡請求(例如GET);
AFHTTPSessionManager內部調用dataTaskWithHTTPMethod:方法(內部處理requestSerializer);
dataTaskWithHTTPMethod內部調用父類AFURLSessionManager的dataTaskWithRequest: uploadProgress: downloadProgress: completionHandler方法;
AFURLSessionManager中的dataTaskWithRequest方法內部設置全局session和創建task;
AFURLSessionManager中的dataTaskWithRequest方法內部給task設置delegate(AFURLSessionManagerTaskDelegate);
taskDelegate代理的初始化: 綁定task / 存儲task下載的數據 / 下載或上傳進度 / 進度與task同步(KVO)
task對應的AFURLSessionManagerTaskDelegate實現對進度處理、Block調用、Task完成返回數據的拼裝的功能等;
setDelegate: forTask: 加鎖設置通過一個字典處理Task與之代理方法關聯; 添加對Task開始、重啓、掛起狀態的通知的接收.
[downloadTask resume]後執行開始, 走代理回調方法(內部其實是NSURLSession的各種代理的實現);
task完成後走URLSession: task: didCompleteWithError: 回調對返回的數據進行封裝;
同時移除對應的task; removeDelegateForTask: 加鎖移除8中的字典和通知;

AFN請求過程梳理

首先我們是初始化了AFHTTPSessionManager類(往往創建單例)初始化時候指定請求回調的代理是父類(AFURLSessionManager)。之後當我們發出一個請求後,先創建一個AFURLSessionManagerTaskDelegate對象來保存請求結果回調。並把該對象放到一個全局字典中來保存(以task.taskIdentifier爲key),再啓動請求。當AFURLSessionManager類收到了請求結果後根據task.taskIdentifier從全局字典中取出當前請求的AFURLSessionManagerTaskDelegate對象。然後調用AFURLSessionManagerTaskDelegate的對象方法處理請求,完成回調。之後再從全局字典中移除該AFURLSessionManagerTaskDelegate對象。

AFN是怎樣來解決循環引用的

首先我們用AFN時候往往是用單例,因此調用類不會直接持有該AFHTTPSessionManager對象。
該AFHTTPSessionManager對象持有block,該AFHTTPSessionManager對象持有全局字典,該全局字典持有AFURLSessionManagerTaskDelegate對象,該AFURLSessionManagerTaskDelegate對象持有block,這是一個循環引用。
當AFURLSessionManagerTaskDelegate對象block進行回調後,從全局字典中移除該對象。從而打破引用環。

1、AFN2.x爲什麼添加一條常駐線程?

AFN2.0裏面把每一個網絡請求的發起和解析都放在了一個線程裏執行。正常來說,一個線程執行完任務後就退出了。開啓runloop是爲了防止線程退出。一方面避免每次請求都要創建新的線程;另一方面,因爲connection的請求是異步的,如果不開啓runloop,線程執行完代碼後不會等待網絡請求完的回調就退出了,這會導致網絡回調的代理方法不執行。
這是一個單例,用NSThread創建了一個線程,並且爲這個線程添加了一個runloop,並且加了一個NSMachPort,來防止runloop直接退出。 這條線程就是AF用來發起網絡請求,並且接受網絡請求回調的線程,僅僅就這一條線程

2、AFN3.x爲什麼不再需要常駐線程?

NSURLConnection的一大痛點就是:發起請求後,這條線程並不能隨風而去,而需要一直處於等待回調的狀態。
蘋果也是明白了這一痛點,從iOS9.0開始 deprecated 了NSURLConnection。 替代方案就是NSURLSession。

3、爲什麼AF3.0中需要設置self.operationQueue.maxConcurrentOperationCount = 1;而AF2.0卻不需要?

功能不一樣:AF3.0的operationQueue是用來接收NSURLSessionDelegate回調的,鑑於一些多線程數據訪問的安全性考慮,設置了maxConcurrentOperationCount = 1來達到串行回調的效果。
而AF2.0的operationQueue是用來添加operation並進行併發請求的,所以不要設置爲1。

AFNetworking3.0

在AFNetworking 3.0之前,底層是通過封裝NSURLConnection來實現的。
在AFNetworking 3.0之後,也就是在iOS 9.0 之後,NSURLConnection被棄用,蘋果推薦使用NSURLSession來管理網絡請求,所以AFNetworking 3.0之後,底層是通過封裝NSURLSession來實現的。

從AFNetworking 3.0中之後,下面三個方法被棄用了。
AFURLConnectionOperation
AFHTTPRequestOperation
AFHTTPRequestOperationManager

依次被下面三個類代替了,同時請求方法也跟着改變了,所以AFNetworking 3.0以後發生了很大的變化。
AFURLSessionManager
AFHTTPSessionManager
AFNetworkReachabilityManager

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章