當前位置:
首頁 > 最新 > iOS源碼補完計劃-AFNetworking 3.1.0源碼研讀

iOS源碼補完計劃-AFNetworking 3.1.0源碼研讀

參拜一下AFNetworking的源碼。

第四篇源碼、暫時來看也是iOS方向的最後一篇、擼完準備趁著熱乎擼一擼網路協議。

準備工作

功能模塊

AFURLSessionManager/AFHTTPSessionManager

在監聽屬性的時候、可以用NSStringFromSelector(@selector(xxx))這種方式來自動提示。

功能AIP分層

如何防止block循環引用

把NSURLSession眾多代理轉化成了block

消除編譯器clang警告

正則的簡便寫法

如何做到對外只讀、對內讀寫

核心代碼

一些比較有意思的東西

AFNetworkReachabilityManager

關於FOUNDATION_EXPORT和UIKIT_EXTERN的選擇

.#if - #esle - #endif

註冊鍵值依賴

四種網路狀態

開始暫停

狀態改變的回調block

核心代碼

知識點

AFSecurityPolicy

__Require_Quiet判斷

.cer文件在iOS里如何使用的

三種驗證模式

核心代碼

知識點

AFHTTPRequestSerializer

AFHTTPResponseSerializer

協議的應用

如何在一個方法中返回兩個NSError

NSIndexSet對象

伺服器返回的圖片是壓縮過的

AFURLResponseSerialization協議以及其解碼方法

核心代碼

知識點

參考資料

準備工作

使用版本3.1.0

推薦在看AFN之前、先了解一下NSURLSession

不然感覺會看的一頭霧水、也體會不到AFN的偉大之處

功能模塊

除了這四個服務性模塊之外、UIKit文件夾下基本是對各種UI控制項的擴展。

AFURLSessionManager/AFHTTPSessionManager

AFURLSessionManager流程

承接了主要的網路傳輸任務、實現了NSURLSession絕大部分的代理方法。

核心代碼

一些比較有意思的東西

在監聽屬性的時候、可以用NSStringFromSelector(@selector(xxx))這種方式來自動提示。

因為屬性本身就是與其get方法同名、可以降低出錯概率。

功能AIP分層

AFURLSessionManager實現了所有的NSURLSessionDelegate。但同時又將其中某些需要處理複雜邏輯的代理傳遞給了AFURLSessionManagerTaskDelegate。使得代碼更清晰、邏輯更明確。需要注意的是、AFURLSessionManagerTaskDelegate完全包裹在了AFURLSessionManager內部、外界完全感受到他的存在。但是又能做數據處理、這個架構設計真心很贊。

除此之外、AFURLSessionManager與AFHTTPSessionManager之間也做了很好的分層。

你可以單獨使用AFURLSessionManager進行網路會話、也可以通過AFHTTPSessionManager更好的使用AFURLSessionManager進行HTTP請求。

如何防止block循環引用

其實我幾年前就聽說AFN可以防止循環引用、但是一直沒看。

今天找了找發現似乎已經沒有了這段代碼,所以個人推測現在不會引起循環引用的原因、應該是因為AFN都在作為單例使用、和self並不互相持有。

貼一段以前別人帖子里的代碼:

把NSURLSession眾多代理轉化成了block

這個說實話我並不太暫停...

個人感覺block就是應該控制個數、而NSURLSession的代理加起來起碼有二三十個。

如果到了這種數量級的數據傳遞、真的還是用代理吧、饒了我。

消除編譯器clang警告

其中Wgnu可以換成其他具體命令

正則的簡便寫法

講道理我還真第一次見

如何做到對外只讀、對內讀寫

AFNetworkReachabilityManager

AFN中負責網路狀態模塊。在不同的網路狀態下可以監聽、或者實時查詢、並且需要手動開啟或者關閉。

四種網路狀態

未知、無網路、運營商網路、WiFi網路

開始暫停

狀態改變的回調block

知識點

關於FOUNDATION_EXPORT和UIKIT_EXTERN的選擇

都可以代替宏來定義常量

有人說是如果文件基於FOUNDATION則用前者、反之則用後者。

二者都能替代#define、並且通過地址比對常量(也就是可以通過 == 直接進行比較)、效率更高。

#if - #esle - #endif

用普通的if-else也是一樣、好處就是在編譯階段是否會被編譯。

不過、#if - #esle - #endif不能用來判斷一個動態的語法。

註冊鍵值依賴

KVO的一個冷門方法

當return的 值被改變的時候、觸發key的監聽,也就是說當networkReachabilityStatus改變的時候、reachable/reachableViaWWAN/reachableViaWiFi的KVO監聽都將被觸發

AFSecurityPolicy

負責網路安全策略(證書)的驗證模塊

核心代碼

.cer文件在iOS里如何使用的

整個驗證都是基於SecTrustRef的、和.cer文件的關係大概是:

NSData格式的證書==>SecCertificateRef==>SecTrustRef對象

而SecTrustRef、就是一個內部至少攜帶了證書與公鑰的結構體。

三種驗證模式

無條件信任伺服器的證書、對公鑰驗證、對證書驗證的具體邏輯。

其實整個模塊也沒有太多可以研究的地方、因為都是固定的方法。你只能這麼寫~

不過、一行一行看一看。iOS的證書到底是如何驗證的、也不錯。

知識點

__Require_Quiet判斷

宏__Require_Quiet和__Require_noErr_Quiet作用其實和if-esle差不多、但是可以從多個入口跳到統一的出口、相關函數__Require_XXX基本都是這個意思。寫了幾個小方法、想看的自己可以copy運行一下

這樣、我們就有了三種判斷的方式

1、普通邏輯的if-else

2、編譯級別的#if - #esle - #endif

3、__Require_XXX這種多入口、統一出口的宏判斷

AFHTTPRequestSerializer

負責網路請求NSMutableURLRequest對象的初始化以及請求頭、請求體、參數、上傳文件的自動化配置。幾千行代碼、很長。但是讀下來會受益匪淺。

流程圖

AFHTTPRequestSerializer流程圖

流程看起來很簡單、但是具體實施起來卻有很多東西。

包括如何將參數字典轉化成字元串並且轉譯、如何進行文件的分段拼接拷貝、如何將一個個請求體文件整合到request中等等。

AFHTTPResponseSerializer

主要看了看AFURLResponseSerialization的內容,負責網路請求成功之後伺服器返回的響應體進行格式化。

核心代碼

AFURLResponseSerialization協議以及其解碼方法

針對不同的解析器(JSON/XML/PList等)、通過實現這個協議的方式。

在請求結束時、幫助AFURLSessionManager對獲得的響應體進行解析。

知識點

1、協議的應用

通過讓多個對象遵循同一份協議的方式、可以在解耦的時候代替繼承、然後重載父類方法時通用做法。使得一個協議、返回不同的結果。

在多人協作的時候、約定好協議然後交由其他業務實現、也是提升開發效率很普遍的方式。

2、如何在一個方法中返回兩個NSError

可以使用嵌套的方式、比如NSUnderlyingErrorKey來指定一個最主要的錯誤。

3、NSIndexSet對象

NSIndexSet這個合集、是NSSet的數字版。

一個無符號整數的集合、內部元素具有唯一性。

內部元素會自動排序

4、伺服器返回的圖片是壓縮過的

伺服器返回的圖片、需要被解壓出bitmap信息。

bitmap的作用在於在將UIImage交付給UIImageView的時候。

如果沒有bitmap將會在主線程自動解壓一次。

參考資料

馬在路上:一個寫了很多源碼解讀的大神


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Cocoa開發者社區 的精彩文章:

10條Swift小提示
WWDC 18:開發者的最初觀感

TAG:Cocoa開發者社區 |