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將會在主線程自動解壓一次。
參考資料
馬在路上:一個寫了很多源碼解讀的大神
TAG:Cocoa開發者社區 |