iOS SDwebImage源碼解析

http://www.cnblogs.com/polobymulberry/category/785704.html
http://www.open-open.com/lib/view/open1456965631750.html
http://my.oschina.net/cao6793569/blog/497399
http://www.cnblogs.com/fyongbetter/p/5629647.html
http://www.360doc.com/content/15/0713/07/26281448_484554873.shtml
http://www.cnblogs.com/leeN/p/4975001.html

經常面試遇到 這樣的面試官 來 小伙你給我說一下 SDwebimage 是什么原理,
然后會有百分之八十的iOS人員會回答 ,他用用來圖片處理 以URL 為名字將圖片存在內存和硬盤里.用的時候依次去去緩存,如果沒有再去請求 然后再把他們緩存到內存和硬盤,最后顯示出來.這么回答沒有錯,一開始我也是這么回答.但是個人感覺凡是這么回答的人 九成是沒有真正的了解和看過他的源碼的.就是在哪里看了一個 iOS的面試寶典的答案,就以為了解啦.
接下來我們將對 SD的源碼進行一遍簡單的梳理,
通過使用時的梳理可以看到的最后到的是這個函數


DB75055D-2B40-4A60-9C00-2834BADF2B48.png

可以看出來1.先把先前的線程停止加載
2.然后給UIview 關聯的一個屬性,屬性的值是圖片URL
3.通過manger 的到一個operation 可以看出來圖片的下載和緩存是在manager里面完成的.
在manager中找了上面3這個函數.


54594C1B-CA7F-4953-A53F-C1ACEB53DD44.png

36C993E8-9382-49A4-B6D7-0BA32DE72220.png

根據名字可以看出來是,是查詢磁盤的緩存目錄更具key (url),返回值是一個NSopreation


4C21C3EE-9B66-4696-8503-D03629A5474B.png

可以看到這個函數中的功能就是
1.在內存中查找圖片,然后block回調參數 圖片和緩存類型
2.如果內存中沒有那么開啟異步線程,獲取瓷盤中的的圖片,然后存在內存中,回到主線程回調磁盤圖片,然后返回這個線程
3.可以看出來,如果內存存在就不會返回 opreation. 如果沒有就會返回opreation
好,我們接著看上一個函數block回調以后的處理,里面有一個這樣的函數
這個函數里面會看到一個函數:


78E7C3E4-984B-4D14-BAA3-4CBE933F9948.png
,根據名字可以看出功能是根據URL 下載圖片,
BD4240B9-1C5E-4DAD-8F4D-4BEFD094BB3F.png

進入這個函數以后可以看到 執行了 調用函數1


1D45F8F2-D078-4FC0-B865-9DCEAA424A73.png
5EA53DD3-51A3-4A27-BA5B-61A1C8693739.png

說實話 看不明白這些


29FA03A8-543C-462C-A460-7ABD3D00438A.png
5F9B3A18-BA7B-444F-A524-6ACF4DDACCD5.png

B8B9224C-4A35-4060-8DA2-E9A3FBFC2D81.png

那么最后在返回開始的地方


70504E4C-1FE6-4DA7-87B5-B6D0BC366991.png

1.加載圖片2.加載暫未圖,3.返回數據4.取消線程,5,返回錯誤

57A62772-C85B-4EFA-8B40-1D480048BEF6.png

其實寫到這里,大概的思路已經清晰啦,但是還是很模糊,感覺是囫圇下肚.還沒有西西的消化.

接下來我們簡單的歸納一下
涉及到的類:

![ ![ ![44A06F6F-6837-45AE-B38C-64EC82242250.png](http://upload-images.jianshu.io/upload_images/1907672-3a58bc9af85c02bc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ](http://upload-images.jianshu.io/upload_images/1907672-2ef49cf62455ae78.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ](http://upload-images.jianshu.io/upload_images/1907672-8f0f84b2d04efb56.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

當然,里面還涉及到了其他的一些,一會接著一一解讀,
UIImageview+WebCaChe 可以看出來是這是一個關于UIimageview的分類
SDWebimageManager 是一個管理者 才像是一個管理整體的把
SDiMAGEcAChe 圖片混存的
Downloader 是用來下載的

我們先看整體的 UIImageview+WebCaChe


D8945E76-86CD-4CE0-BE56-7E00A3649CC4.png

這里面使我們最常用的一個方法,用URL 和展位圖設置空間的圖片,是異步的并且可以緩存/

![B2CF8E0C-0E4E-479B-BE44-0E42CB8862F1.png](http://upload-images.jianshu.io/upload_images/1907672-883585dd0f84f36e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

然后就去了manager去下載
這個是manager的初始化方法


AA821A4A-927D-45F2-9E54-6467AF74DB3E.png

這里單例new了一個manager,new 其實就是init 接著創建了
SDImageCache SDWebImagerDownLoader倆個類 這里是他的初始化方法.


F7C6CF58-2AC2-4C75-86C7-2E244B3A4F93.png
根據URL 獲取圖片純存儲的key,如果存在則取出,
046E08C5-C6DD-49FA-AD1B-021A8AB6E21C.png

根據URL 判斷內存和磁盤中時候含有圖片,這里用到了SDImageCache這個類


F6C50A1C-FDAC-4DE2-955A-2406E9D6053F.png

這里是更具URL 轉換成的key 去取圖片 內存和磁盤.這樣,如果得到就在block中返回yes. 這里也用到了SDImageCache 和他的方法.


B27EA926-7E08-47B0-8FB0-38C6414C5DB0.png

存儲圖片和取消全部的線程
B62B240F-C4C4-4AA4-AD04-FA0190CFE2E2.png

再有就是這個函數 ,也就是前面 UIimageview+cache 分類中調用的方法.
先大概了解一下下面的東西


856D2F36-7C3C-49BC-8E67-604D75E30ED4.png
3F5370A4-7922-456C-858E-B7FF1CFD07E9.png

-(BOOL) respondsToSelector: selector 用來判斷是否有以某個名字命名的方法(被封裝在一個selector的對象里傳遞)

12A08F5A-2728-4312-8920-79102ECD4B63.png

把線程添加到數組中,如果線程已經取消那么這移除,然后判斷下一下 將圖片和 緩存類型返回.


425FE1AF-023A-442F-AD81-6296DFC527EB.png

設置options 但是我有點看不太明白

E20098E5-4F71-4B09-8E00-949F3865C818.png

將不合法的URL添加到黑名單


1F81BD28-ABF9-44FC-B78C-68B910CF774B.png

大概意思就是 即使圖片已經被緩存啦 ,他還會在去遠程請求圖片.(不知道這個是什么機制怎么做到的啊)

146B3730-F9AB-480D-A245-62F25A594682.png

如果需要刷新圖片那么就不做操作
制定了一個代理 用來旋轉圖片,旋轉完以后,然后將圖片存儲在imageCache.而且是存在 磁盤,因為前面已經判斷了 option 時候是存在內存的

C2871636-2186-4A51-9FA9-5F68475BE2E9.png

這個就不解釋啦 就是存儲

9187A940-D351-4292-A1E2-5FE40C63A42A.png

/auto-orient/strip%7CimageView2/2/w/1240)
如果 沒有 options 那么久可以直接 block返回圖片 再不然就返回空.這個函數結束,最后返回一個opreation
manager總結
整體就是
1.先判斷URL 是否是在黑名單中,如果在那么就結束,
2.然后判斷是否有錯,如果有直接block返回 然后結束
3.將去磁盤和內存中去尋找圖片,這是判斷option 如果options是SDWebImageRefreshCached 那么直接去重新下載
4.這時如果沒有圖片或者需要刷新圖片時,那么開始下載
5.同樣判斷線程是否存在,是否有錯誤返回,然后判斷URL的是否可用然后加入黑名單
6.接下來就是看一下options 有沒有要求之緩存在內存,如果沒有的話,那么就緩存到磁盤和內存,同事判斷是否要求刷新內存,如果要這步做處理
7.再就是判斷是否需要旋轉SDWebImageTransformAnimatedImage 通過代理實現并且返回旋轉后的圖片
8.下載完成以后就緩存

manager中涉及到了其他類
SDWebImageCombinedOperation
SDImageCache
SDWebImageDownloader

接著呢,我們就看一下  SDWebImageCombinedOperation   

![56CD83B1-A1CD-40CB-A764-EA1039350CF3.png](http://upload-images.jianshu.io/upload_images/1907672-ff465a078adeb797.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
可以看出來 他是繼承與 NSoperation  并且準守了是哪個協議,后兩個是是網絡請求的  session 
![F140D943-A53E-4461-AB55-E69A5396DD2C.png](http://upload-images.jianshu.io/upload_images/1907672-e0c6b048bdca5d31.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
下一篇http://www.lxweimin.com/p/d11815de83ec
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容