SDWebImage源碼解讀(一)

SDWebImage是我們常用的圖片緩存加載庫,我們有必要對源碼進行仔細閱讀與學習,以便了解更多SD支持的功能與實現(xiàn)原理,并且在遇到問題時能及時的進行調(diào)試解決。我們再閱讀之前先自己想想一下,如果我們自己來實現(xiàn)這個圖片緩存與加載庫,要怎么實現(xiàn)呢?感覺很簡單就是下載圖片,對UIImage進行賦值,同時對圖片進行緩存方便下次更快的加載。SD作為更優(yōu)秀的框架,有大量的使用者,所以對外提供了很多接口和拓展功能??聪聢D的作者給出的UML圖,可以清晰的看出相互的調(diào)用關(guān)系。

SDWebImage圖片加載的時序圖

SDWebImageSequenceDiagram.png

第一步:調(diào)用對象調(diào)用對外暴露的sd_setImageWithURL(),設(shè)置圖片信息下載的URL和輔助信息

第二步:調(diào)用UIView的sd_internalSetImageWithURL()方法,這一步會首先拿到當前view是否有正在進行的下載opration,如果有進行取消。設(shè)置進度回調(diào)block,拿到SDWebImageManager設(shè)置下載后對應的opration并保存。

第三步:調(diào)用SDWebImageManager的loadImageWithURL方法,此方法首先創(chuàng)建SDWebImageCombinedOperation并進行配置,首先通過imageCache調(diào)用queryDiskCacheForKey()查詢url對應的緩存信息。如果沒有緩存數(shù)據(jù),調(diào)用SDWebImageDownloader的downloadImage方法去下載圖標。待下載完成圖片進行回調(diào),在回調(diào)后Manager使用imageCache進行圖片的緩存。

第四步:通過回調(diào)在獲取到圖片后,SDWebImageManager經(jīng)過一步步的回調(diào),將圖片返回給調(diào)用者。

SDWebImage的基本架構(gòu)

SDWebImageStruct.png
SDWebImage4.3.2.png

見如基本架構(gòu)圖:
左側(cè)為主要實現(xiàn)類,包括:Utils、Downloader、Cache、Decoder這幾個核心模塊
右側(cè)為輔助類,包括:WebCacheCategories、Categories、FLAnimatedImage。這些輔助類主要是輔助對UI的拓展,方便我們使用,比如拓展常用的UIImageView。

重點說一下左側(cè)核心模塊:

Utils

SDWebImageManager:實現(xiàn)圖片下載和緩存的管理,對外提供接口

SDWebImagePrefetcher:實現(xiàn)預加載,可以預先加載一組URL地址對應的圖片

SDWebImageTransition:實現(xiàn)圖片加載完畢后的展示動畫,默認提供了7種,支持拓展

下載模塊:

SDWebImageDownloader:下載中心,管理下載隊列

SDWebImageDownloaderOperation:下載的具體隊列

緩存圖片:

SDImageCacheConfig:緩存的配置信息

SDImageCache:緩存的設(shè)置

解碼中心:

SDWebImageCodersManager:圖片編碼中心,支持拓展

SDWebImageCoder:圖片編碼協(xié)議集,自行拓展的分類必須支持此協(xié)議

SDWebImageImageIOCoder:PNG、JPEG、TIFF圖片的解碼

SDWebImageGIFCoder:GIF的解碼

SDWebImageWebPCoder:Webp的解碼

SDWebImageFrame:動圖設(shè)置相關(guān)類組合

SDWebImageCoderHelper:圖片解碼相關(guān)幫助方法

SDAnimatedImageRep:NSBitmapImageRep的子類,加快NSBitmapImageRep的渲染

UIView(WebCache)的入口模塊

- (void)sd_internalSetImageWithURL:(nullable NSURL *)url
                  placeholderImage:(nullable UIImage *)placeholder
                           options:(SDWebImageOptions)options
                      operationKey:(nullable NSString *)operationKey
                     setImageBlock:(nullable SDSetImageBlock)setImageBlock
                          progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
                         completed:(nullable SDExternalCompletionBlock)completedBlock
                           context:(nullable NSDictionary<NSString *, id> *)context;

具體執(zhí)行順序:

1.判斷當前view是否已經(jīng)有SDWebImageOperation,如果有就將此操作取消并移除。

2.組建下載回調(diào)SDWebImageDownloaderProgressBlock

3.調(diào)用SD獲取圖片

- (id <SDWebImageOperation>)loadImageWithURL:(nullable NSURL *)url
                                     options:(SDWebImageOptions)options
                                    progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
                                   completed:(nullable SDInternalCompletionBlock)completedBlock 

4.主線程更新UI對應的圖片,存儲當前的SDWebImageOperation

SDWebImage的管理模塊

SDWebImageManager是一個管理中心類,本身是一個單例,管理緩存、下載的行為。屬性見下面代碼,持有一個緩存管理對象imageCache、一個下載管理對象imageDownloader、一個下載失敗url的集合failedURLs、一個保存正在進行的Operation的集合runningOperations。

@property (strong, nonatomic, readwrite, nonnull) SDImageCache *imageCache;
@property (strong, nonatomic, readwrite, nonnull) SDWebImageDownloader *imageDownloader;
@property (strong, nonatomic, nonnull) NSMutableSet<NSURL *> *failedURLs;
@property (strong, nonatomic, nonnull) NSMutableArray<SDWebImageCombinedOperation *> *runningOperations;

其包含一個內(nèi)部類-SDWebImageCombinedOperation類,主要用于保存當前任務(wù)的所有模塊狀態(tài),以便在需要取消所有操作的時候進行取消。持有四個屬性,分別為是否取消cancelled,下載的管理模塊返回的downloadToken,緩存的任務(wù)cacheOperation,當前控制器manager。

@property (assign, nonatomic, getter = isCancelled) BOOL cancelled;
@property (strong, nonatomic, nullable) SDWebImageDownloadToken *downloadToken;
@property (strong, nonatomic, nullable) NSOperation *cacheOperation;
@property (weak, nonatomic, nullable) SDWebImageManager *manager;

SDWebImageManager核心方法
- (nullable id <SDWebImageOperation>)loadImageWithURL:(nullable NSURL *)url
                                              options:(SDWebImageOptions)options
                                             progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
                                            completed:(nullable SDInternalCompletionBlock)completedBlock;

具體執(zhí)行順序:

1.創(chuàng)建一個SDWebImageCombinedOperation類operation,用于保存當前任務(wù)的所有信息。并用runningOperations保存此operation。

2.緩存中心,查詢url對一個的緩存信息是否存在。查詢時,先直接查詢內(nèi)存緩存是否存在,有就返回。沒有的話異步查詢硬盤緩存,同時將查詢緩存的operation返回,讓SDWebImageCombinedOperation進行保存。

- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options done:(nullable SDCacheQueryCompletedBlock)doneBlock;

3.根據(jù)緩存情況和用戶配置,調(diào)用imageDownloader的下載方法進行下載,同時將下載的模塊的返回token,
讓SDWebImageCombinedOperation進行保存。

- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url
                                                   options:(SDWebImageDownloaderOptions)options
                                                  progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
                                                 completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;

4.圖片下載完成后,根據(jù)用戶的配置做后續(xù)操作,如保存圖片信息到緩存模塊,完成后的回調(diào),runningOperations刪除當前進行的任務(wù)。

總結(jié):

本文對SD的所有模塊進行整體的拆分,并對類別入口模塊和中心管理模塊SDWebImageManager核心方法進行解析。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容