一、 SDWebImage原理簡介
1.結構 (設計思路借鑒:提供多種接口,到底層調用到同一個方法,減少調用方對可選參數的傳遞)

UIImageView+WebCache和UIButton+WebCache直接為表層的 UIKit框架提供接口,
SDWebImageManger(SDWebImageManager是SDWebImage的核心類,也是我們經常接觸到的類)負責處理和協調SDWebImageDownloader和SDWebImageCache, 並與UIKit層進行交互。SDWebImageDownloaderOperation真正執行下載請求;
SDWebImageManger詳解:https://www.jianshu.com/p/246f6303cb6f
最底層的兩個類為高層抽象提供支持。
SDWebImageCompat 是最基礎的配置文件,為了兼容蘋果各個平台
SDWebImageCompat 詳解:https://www.jianshu.com/p/cfdd59d7df7c
SDWebImageDecoder sd解碼圖片這個類其實是UIImage的一個分類UIImage+ForceDecode,主要用來解碼UIImage
SDWebImageDecoder 詳解: https://www.jianshu.com/p/e631b4b2a214
結構關系圖

結構詳圖(類圖)

2.原理
一張圖片加載的全過程:
- 我們在使用
SDWebImage時調用了[imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]];這個簡單的分類方法,然后就靜靜的等着圖片被設置到UIImageView類對象上。 - 經過一系列調用,我們首先來到
UIView+WebCache分類中,在這個分類中,首先保障了圖片加載的唯一性,然后就開始了核心的加載操作。 - 接着就進入了
SDWebImageManager類中,在這個類中,首先去查找是否有緩存,沒有緩存的話才去服務器下載。 - 想要查找緩存我們要進入
SDImageCache這個類中,在這個類中,首先去內存中查看是否有對應的緩存,如果沒有再去硬盤中查找是否有對應的緩存,但是從硬盤中獲取的是圖片的數據,要想獲得圖片還要經歷解碼、縮放和解壓。當然如果都沒有緩存的話就去下載。 - 負責下載的是
SDWebImageDownloader這個類,在這個類中,將圖片的下載操作封裝成了自定義的一個類SDWebImageDownloaderOperation,然后添加到了操作隊列中。 - 當操作隊列調用這個操作時,會調用操作對象的
- (void)start方法,在重寫的這個方法中,生成了任務對象dataTask,並調用resume開始執行任務。 - 因為
SDWebImageDownloaderOperation類遵守了dataTask對象的協議,所以dataTask執行的結果會通過代理方法進行回調。在代理方法中,獲取並保存了服務器返回的數據,並在任務執行結束后,對數據進行解碼、縮放和解壓。處理完成后就進行回調。 - 通過重重回調,要回調的數據沿着
SDWebImageDownloaderOperation->SDWebImageDownloader->SDWebImageManager->UIView+WebCache一路流動,其中流動到SDWebImageManager中時對圖片進行了緩存,最后在UIView+WebCache中為UIImageView設置了處理好的圖片。 - 這就是
SDWebImage加載圖片的大體流程,當然還有非常多的小細節和小功能,這些就在以后對具體類的閱讀中學習了。
運行時序圖

運行流程圖

3.源碼解讀(詳解可看其中相關鏈接)
詳解:https://juejin.im/post/5adff5636fb9a07aa213026b
二、SDWebImage4.0、5.0對比
4.0源碼解析 :https://juejin.im/post/5bbec080e51d450e4d3021c0
5.0源碼解析:https://www.jianshu.com/p/8af8fc7cd5bc
1.項目中結構(還是一樣的,不像網上資料說的 變更了結構)

2.文件對比 5.0比4.0多出 61個文件(114+2-55)

3.SDAnimated 4.0只是為了處理GIF 5.0可以處理動畫




4.Cache 充分體現SRP(單一職責)開發原則 ,緩存處理更加完備 專門的磁盤緩存處理類 內存緩存處理類
SDImageCache是SDWebImage的緩存類,是SDWebImage的重要組成部分,主要提供圖片的緩存,和提取,分為內存緩存和磁盤緩存兩種,因為SDWebImage的接口性設計,SDImageCache完全可以單獨拿出來使用
詳解:https://www.jianshu.com/p/f8f724bb0f4b



5.Coder(圖片編解碼器) 方法命名少了Web
SDWebImage里自己寫了一個編解碼管理器,用於實現編碼,解碼,壓縮,縮小圖片像素功能。涉及到的文件有SDWebImageCodersManager,SDWebImageCoder,SDWebImageImageIOCoder等等
詳解 :https://www.jianshu.com/p/615d3178a508

6.Loader 圖片下載 充分體現SRP(單一職責)開發原則,區分更加明顯 類的功能更加單一 ,SDWebImageError 4.0沒有 5.0專門的錯誤處理
SDWebImageDownloader和SDWebImageDownloaderOperation 是 SDWebImage的下載類,是SDWebImage的很重要的一個類,這個類主要負責圖片的下載
詳解:https://www.jianshu.com/p/a77fd7b09bd1

7.應用層 (多了4個文件,但跟實際使用沒有多大關系)
/**
UIImage category for image metadata, including animation, loop count, format, incremental, etc.
*/
用於圖像元數據的ui圖像類別,包括動畫、循環計數、格式、增量等
@interface UIImage (Metadata)
/**
Provide some commen method for `UIImage`.
Image process is based on Core Graphics and vImage.
*/
@interface UIImage (Transform)
為“uiimage”提供一些通用方法,拉伸,裁剪,圓角等等。
圖像處理基於Core Graphics 和 vImage

8.引入SDWebImageContext / SDWebImageMutableContext

可以看到SDWebImageContext / SDWebImageMutableContext 其實就是
以 SDWebImageContextOption為key、id(指定類型或者協議)為value 的NSDictionary/NSMutableDictionary
typedef NSDictionary<SDWebImageContextOption, id> SDWebImageContext;
typedef NSMutableDictionary<SDWebImageContextOption, id>SDWebImageMutableContext;
而 SDWebImageContextOption 是一個可擴展的String枚舉
typedef NSString * SDWebImageContextOption NS_EXTENSIBLE_STRING_ENUM;


SDWebImage定義了10個SDWebImageContextOption的key、對應的value類型和定義的位置
| Key |
Value |
Define |
| SDWebImageContextSetImageOperationKey |
NSString |
SDWebImageDefine.m |
| SDWebImageContextCustomManager |
SDWebImageManager |
SDWebImageDefine.m |
| SDWebImageContextImageTransformer |
id<SDImageTransformer> |
SDWebImageDefine.m |
| SDWebImageContextImageScaleFactor |
CGFloat |
SDWebImageDefine.m |
| SDWebImageContextStoreCacheType |
SDImageCacheType |
SDWebImageDefine.m |
| SDWebImageContextDownloadRequestModifier |
id<SDWebImageDownloaderRequestModifier> |
SDWebImageDefine.m |
| SDWebImageContextCacheKeyFilter |
id<SDWebImageCacheKeyFilter> |
SDWebImageDefine.m |
| SDWebImageContextCacheSerializer |
id<SDWebImageCacheSerializer> |
SDWebImageDefine.m |
| SDWebImageContextLoaderCachedImage |
UIImage/NSImage<SDAnimatedImage> |
SDImageLoader.m |
通過圖片看下SDWebImageContext有多重要

從上圖可以看到,SDWebImageContext就像一條「流水線」,把里面的參數項從最外層的View層一直傳遞到SDImageCache和SDWebImageDownloaderOperation。「流水線」經過的各個模塊會從上去各自取自己感興趣的東西使用(彩色實心箭頭)
詳解:https://www.jianshu.com/p/cfde8db5c051
9.協議化了很多重要的對象。(靈活)
之前要做某個操作必須用該對象 現在任何對象都可以 只要遵守了協議就可以
配合新引入的 SDWebImageContext/SDWebImageMutableContext 參數,保留快速使用特性的同時可以靈活的自定義高級功能
| 4.4 |
5.0 |
| SDWebImageCacheSerializerBlock |
id<SDWebImageCacheSerializer> |
| SDWebImageCacheKeyFilterBlock |
id<SDWebImageCacheKeyFilter> |
| SDWebImageDownloader |
id<SDImageLoader> |
| SDImageCache |
id<SDImageCache> |
| SDWebImageDownloaderProgressBlock |
id<SDWebImageIndicator> |
詳解:https://www.jianshu.com/p/cfde8db5c051
10.UIImage+GIF 方法變更

備注:
1.NS_EXTENSIBLE_STRING_ENUM 字符串類型枚舉

