iOS經常使用第三方框架的工做原理

在寫iOS項目的過程當中,咱們常常會用到AFNetworking和SDWebImage這種第三方開源框架,但其工做原理咱們大部分人都不怎麼清楚,在這裏整理一下這兩個第三方開源框架的工做原理。前端

1.介紹

1.AFNetworking
AFNetworking庫,我認爲是目前最優秀的開源網絡庫,基於NSURLConnection,目前咱們最可能用到的地方是JSON請求或者XML請求;能夠設置GET或者POST方式提交數據,而GET或者POST的NSURLRequest,和NSURLConnection使用GET和POST方式徹底同樣
2.SDWebImage
SDWebImage庫提供一個UIImageView類別以支持加載來自網絡的遠程圖片。具備緩存管理、異步下載、同一個URL下載次數控制和優化等特徵。
另外,這兩個庫都是基於GCD的.
web

2.綜述

一.AFNetworking

AFNetworing除了幾個分類外的全部類。類庫的頭文件AFNetworking.h引入了下面的全部類庫,並能夠根據不一樣的系統使用不一樣的實現方式。下面大致介紹下每一個類的大體做用,主要以翻譯API的註釋文檔爲主緩存

1:AFURLConnectionOperation能夠說是AFN最基礎的類。繼承自NSOperation類,將網絡請求依附到一個operation上。從而讓咱們可以有效的控制並觀察一個網絡請求的建立、進行、取消、完成、暫停恢復、異常等問題及狀態。【重點類的實現分析】安全

2:AFHTTPRequestOperationHTTP或HTTPS協議請求的AFURLConnectionOperation的子類。它封裝的可接受狀態碼和內容的類型,斷定一個請求結果是成功或失敗。實際上對系統的HTTP網絡請求增長了幾個HTTP須要用到的參數。服務器

3:AFHTTPRequestOperationManager這個類是AFN類庫的核心類。它封裝完成了一種通用的模式,能夠幫助咱們輕鬆友好的完成請求的建立、響應的系列化,網絡狀態的監控以及安全策略以及每個請求operation的管理(operation的相互依賴或狀態改變)。【重點類的實現分析】
4:AFURLSessionManageriOS7 以後,蘋果增長了新的網絡請求類--NSURLSession。AFN官方推薦iOS 7 或者 Mac OS X 10.9以上的,最好使用該類發起網絡請求,取代AFHTTPRequestOperationManager。不過基於目前國內app大都最低適配的 iOS6,該類的用途還不是太普遍。NSURLSession的說明或者使用再也不贅述。自行查看API文檔。之後有時間再加上該類的使用。
網絡

5: AFURLSessionManager繼承自AFURLSessionManager。相似於1和2的關係。也是方便HTTP以及https請求的使用,增長了一些接口,方便調用。併發

6:AFNetworkReachabilityManager網絡的連通狀態監控以及網絡的類型。實際是將蘋果官方提供的Reachability的類名和通知名更換了一下,防止和系統提供的類的通知名以及類名的衝突。app

7:AFSecurityPolicy這個我不太懂,安全策略的類。通常貌似用不到,有須要自行google。框架

8:AFURLRequestSerialization①:符合這個協議的對象用於處理請求,它將請求參數轉換爲 query string 或是 entity body 的形式,並設置必要的 header。②:構建multipart請求。異步

9:AFURLResponseSerialization遵循AFURLResponseSerialization協議的對象,用於驗證、序列化響應及相關數據,轉換爲有用的形式,好比 JSON 對象、圖像、甚至基於mantle的模型對象。

2.重點類的實現分析

1:AFURLConnectionOperation的實現

①:綜述
AFURLConnectionOperation 將Operation和URLConnection結合到一塊兒,利用operation能夠監聽到狀態以及能夠創建相互之間的依賴關係的特性,實現了對於 一個NSURLConnection對象的完美控制,並將請求的結果經過block友好的返回。

②:實現文件.m
咱們總結下.m中這個類主要有哪些方法。
1: 首先咱們能夠看到它建立了一個單例線程。這個線程將會常駐內存,用來處理AFN發起的全部請求任務。固然,線程也跟隨着一個runloop,AFN將這個 runloop的模式設置爲NSDefaultRunLoopMode。NSDefaultRunLoopMode是沒法檢測到connection的狀 態的。這說明了,AFN將不會在這該線程處理connection完成後的UI刷新等工做,而是會將數據拋給主線程,讓主線程去完成UI的刷新。

2:咱們能夠看到該類經過接受請求的字符串,建立了URLRequest以及NSURLConnection對象。從而去進行請求。

3:實現文件屢次使用到了鎖,能夠保證數據的安全。固然他也實現了幾個數據的NSCoping協議。

4:請求的建立、進行、取消、完成、暫停恢復、異常等問題及狀態的控制。這裏講一下暫停和恢復。暫 停實際上將網絡請求取消掉了。可是因爲實現了nscoping協議,已經下載到數據得以保存下來。下次進行相同請求的時候,咱們會將已經下載到的數據的節 點一塊兒發送給服務器,告訴服務器這些部門的數據咱們不須要了,服務器根據我發送的返回節點給我返回相應的數據便可。從而實現了暫停和恢復功能,也就是斷點 續傳。

5:operation方法的重寫。自行google,這裏不贅述。

6:狀態的各類控制方法的實現以及發送狀態改變的通知

③:接口文件.h
接口文檔中的屬性方法,基本能夠歸納爲如下幾個方法
1:只讀的數據,讓管理者能夠接收到。
2:設置runloop的modes。再也不使用類庫默認設置的defaultmodes。
3:狀態的控制方法
4:安全策略的設置
總而言之,接口文件.h暴露的接口都是爲了讓manager能夠去徹底控制這個operation以及其中的網絡請求。

2:AFHTTPRequestOperationManger
①:綜述
這個類能夠說是整個類庫的核心類了。聽說AFN2.0以前的時候,全部的網絡請求相關的設置都雜糅到一個client中,致使client特別的臃腫。2.0後,AFN將一些設置提取出來,線程了專門的類【AFSecurityPolicy、AFURLRequestSerialization、AFURLResponseSerialization】。如今看來,AFN總體的設計是很是完美的。耦合性變得很是低,一些1.0版本中存在的問題也獲得了改善。
②:實現文件.m
實現文件較爲簡單,能夠看到他建立了一個隊列。並將各個operation加入到隊列中。在隊列中,各個請求就能夠設置依賴關係,併發的數量等等。
③:接口文件.h
接口文件中,咱們能夠看到。這個類能夠設置AFSecurityPolicy、AFURLRequestSerialization、AFURLResponseSerialization 等參數了。這就是綜述所說的下降耦合性的方式。基本使用很簡單,這裏就再也不贅述了。

二.SDWebImage

SDWebImage庫的做用

經過對UIImageView的類別擴展來實現異步加載替換圖片的工做。
主要用到的對象:
一、UIImageView (WebCache)類別,入口封裝,實現讀取圖片完成後的回調

二、SDWebImageManager,對圖片進行管理的中轉站,記錄那些圖片正在讀取。
向下層讀取Cache(調用SDImageCache),或者向網絡讀取對象(調用SDWebImageDownloader) 。

三、實現SDImageCache和SDWebImageDownloader的回調。

四、SDImageCache,根據URL的MD5摘要對圖片進行存儲和讀取(實現存在內存中或者存在硬盤上兩種實現)實現圖片和內存清理工做。

五、SDWebImageDownloader,根據URL向網絡讀取數據(實現部分讀取和所有讀取後再通知回調兩種方式)
其餘類:
SDWebImageDecoder,異步對圖像進行了一次解壓⋯⋯

SDWebImage 加載圖片的流程

一、入口 setImageWithURL:placeholderImage:options: 會先把 placeholderImage 顯示,而後 SDWebImageManager 根據 URL 開始處理圖片。

二、進入 SDWebImageManager-downloadWithURL:delegate:options:userInfo:,交給 SDImageCache 從緩存查找圖片是否已經下載queryDiskCacheForKey:delegate:userInfo:. 
 
三、先從內存圖片緩存查找是否有圖片,若是內存中已經有圖片緩存,SDImageCacheDelegate 回調 imageCache:didFindImage:forKey:userInfo: 到 SDWebImageManager。
  
四、SDWebImageManagerDelegate 回調 webImageManager:didFinishWithImage: 到 UIImageView+WebCache 等前端展現圖片。若是內存緩存中沒有,生成 NSInvocationOperation 添加到隊列開始從硬盤查找圖片是否已經緩存。
 
五、根據 URLKey 在硬盤緩存目錄下嘗試讀取圖片文件。這一步是在 NSOperation 進行的操做,因此回主線程進行結果回調 notifyDelegate:。
  
六、若是上一操做從硬盤讀取到了圖片,將圖片添加到內存緩存中(若是空閒內存太小,會先清空內存緩存)。SDImageCacheDelegate 回調 imageCache:didFindImage:forKey:userInfo:。進而回調展現圖片。
  
七、若是從硬盤緩存目錄讀取不到圖片,說明全部緩存都不存在該圖片,須要下載圖片,回調 imageCache:didNotFindImageForKey:userInfo:。 
 
八、共享或從新生成一個下載器 SDWebImageDownloader 開始下載圖片。
  
九、圖片下載由 NSURLConnection 來作,實現相關 delegate 來判斷圖片下載中、下載完成和下載失敗。 
 
十、connection:didReceiveData: 中利用 ImageIO 作了按圖片下載進度加載效果。 
 
十一、connectionDidFinishLoading: 數據下載完成後交給 SDWebImageDecoder 作圖片解碼處理。
  
十二、圖片解碼處理在一個 NSOperationQueue 完成,不會拖慢主線程 UI。若是有須要對下載的圖片進行二次處理,最好也在這裏完成,效率會好不少。
  
1三、在主線程 notifyDelegateOnMainThreadWithInfo: 宣告解碼完成,  imageDecoder:didFinishDecodingImage:userInfo: 回調給 SDWebImageDownloader。
  
1四、imageDownloader:didFinishWithImage: 回調給 SDWebImageManager 告知圖片下載完成。
  
1五、通知全部的 downloadDelegates 下載完成,回調給須要的地方展現圖片。
  
1六、將圖片保存到 SDImageCache 中,內存緩存和硬盤緩存同時保存。寫文件到硬盤也在以單獨 NSInvocationOperation 完成,避免拖慢主線程。
  
1七、SDImageCache 在初始化的時候會註冊一些消息通知,在內存警告或退到後臺的時候清理內存圖片緩存,應用結束的時候清理過時圖片。
  
1八、SDWI 也提供了 UIButton+WebCache 和 MKAnnotationView+WebCache,方便使用。 
 
1九、SDWebImagePrefetcher 能夠預先下載圖片,方便後續使用。

寫得不完整的地方,歡迎補充 謝謝~~


 

文/一把豆芽菜(簡書做者) 原文連接:http://www.jianshu.com/p/13572b43caa0 著做權歸做者全部,轉載請聯繫做者得到受權,並標註「簡書做者」。

相關文章
相關標籤/搜索