說白了,這個(gè)框架是一個(gè)異步下載圖片并且支持緩存的 UIImageView 分類
原理圖如下:

最常使用的是這個(gè)方法
[self.imageView sd_setImageWithURL:[NSURL URLWithString:@"url"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
首先我們來以UIImageView+WebCache中- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;這個(gè)方法為入口研究SDWebImage是如何工作的.
當(dāng)我們進(jìn)入到.m實(shí)現(xiàn)文件的時(shí)候如下

發(fā)現(xiàn)這個(gè)方法唯一的作用就是調(diào)用了另一個(gè)方法
[self sd_setImageWithURL:placeholderImage:options:progress:completed:]
其實(shí)仔細(xì)看看暴露給我們使用的方法后,不難看出,最終都會(huì)調(diào)用這個(gè)方法,只是根據(jù)需要傳入的參數(shù)不同而已,無疑這是UIImageView+WebCache中的核心方法
這個(gè)方法具體實(shí)現(xiàn)代碼比較多,大家點(diǎn)擊頭文件都可以看到
操作管理
方法的第一行代碼是
[self sd_cancelCurrentImageLoad];
這是整個(gè)框架管理操作隊(duì)列的方法,寫這個(gè)方法是取消當(dāng)前正在進(jìn)行中的下載(實(shí)際上沒有下載),防止與即將進(jìn)行的操作發(fā)生沖突.會(huì)調(diào)用:
[self sd_cancelImageLoadOperationWithKey:@"UIImageViewImageLoad"]```
###占位圖片
if (!(options & SDWebImageDelayPlaceholder)) {
self.image = placeholder;
}
默認(rèn)情況下options == 0,那么會(huì)為當(dāng)前的UIImageView添加一個(gè)臨時(shí)的image,也就是占位圖.
####獲取圖片
接下來會(huì)檢測傳入的url是否為空,非空全局SDWebImageView會(huì)調(diào)用以下方法獲取圖片
[SDWebImageManager.sharedManager downloadImageWithURL:options:progress:completed:]
下載完后會(huì)調(diào)用```(SDWebImageCompletionWithFinishedBlock)completedBlock```為UIImageView.image賦值,添加上最終所需要的圖片
dispatch_main_sync_safe(^{
if (!wself) return;
if (image) {
wself.image = image;
[wself setNeedsLayout];
} else {
if ((options & SDWebImageDelayPlaceholder)) {
wself.image = placeholder;
[wself setNeedsLayout];
}
}
if (completedBlock && finished) {
completedBlock(image, error, cacheType, url);
}
});
接下來分析SDWebImageManager中的方法
[SDWebImageManager.sharedManager downloadImageWithURL:options:progress:completed:]
####SDWebImageManager
這個(gè)類是用來處理異步下載和圖片緩存的類,
獲取圖片的過程有大體上分為兩部分, 它首先會(huì)在 SDWebImageCache 中尋找圖片是否有對應(yīng)的緩存, 它會(huì)以 url 作為數(shù)據(jù)的索引先在內(nèi)存中尋找是否有對應(yīng)的緩存, 如果緩存未命中就會(huì)在磁盤中利用 MD5 處理過的 key 來繼續(xù)查詢對應(yīng)的數(shù)據(jù), 如果找到了, 就會(huì)把磁盤中的緩存?zhèn)浞莸絻?nèi)存中.
然而, 假設(shè)我們在內(nèi)存和磁盤緩存中都沒有命中, 那么 manager 就會(huì)調(diào)用它持有的一個(gè) SDWebImageDownloader 對象的方法 downloadImageWithURL:... 來下載圖片, 這個(gè)方法會(huì)在執(zhí)行的過程中調(diào)用另一個(gè)方法 addProgressCallback:andCompletedBlock:forURL:createCallback: 來存儲(chǔ)下載過程中和下載完成的回調(diào), 當(dāng)回調(diào)塊是第一次添加的時(shí)候, 方法會(huì)實(shí)例化一個(gè) NSMutableURLRequest 和 SDWebImageDownloaderOperation, 并將后者加入 downloader 持有的下載隊(duì)列開始圖片的異步下載.
而在圖片下載完成之后, 就會(huì)在主線程設(shè)置 image 屬性, 完成整個(gè)圖像的異步下載和配置.
####總結(jié)
整個(gè)框架的圖片加載過程其實(shí)很符合我們常人的邏輯
查看緩存:
a)查看內(nèi)存中(程序可能已經(jīng)加載過這個(gè)圖片)是否有緩存,如果有就返回圖片設(shè)置圖片;沒有就查看磁盤緩存,有就返回圖片并設(shè)置
b)內(nèi)存和磁盤中都沒有緩存,網(wǎng)絡(luò)異步下載圖片,加入磁盤緩存和內(nèi)存緩存,設(shè)置圖片