SDWebImage
SDWebImage的簡單介紹:一款世界級圖片下載緩存框架,添加到工程中不會有煩人的警告
首先SDWebImage的實現(xiàn)原理
SDWebImageManger
是由一個SDWebImageDownloader(負(fù)責(zé)下載網(wǎng)絡(luò)圖片),SDImageCache(一個處理緩存的類)共同構(gòu)成的類
SDWebImage提供了如下三個category來進(jìn)行緩存唉工。
MKAnnotationView + WebCache
地圖大頭針
UIButton + WebCache
給按鈕設(shè)置圖片
UIImageView + WebCache
imageView的圖片
SDWebImage的常用方法介紹
在給tableView設(shè)置圖片時可以用到SDWebImage中
UIImageView + WebCache
分類中下面一個重要的方法
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
這個方法在以前的版本中是沒有sd_前綴的,里面的參數(shù)很容易理解,這里重點介紹一下options這個參數(shù):
options是SDWebImageOptions類型的枚舉類型,里面有10個選項,下面一一進(jìn)行介紹
SDWebImageRetryFailed = 1 << 0, 默認(rèn)情況下,當(dāng)一個 URL 下載失敗,會將該 URL 放在黑名單中,不再嘗試下載,當(dāng)使用這個標(biāo)記時就會 ,取消黑名單意思是即使下載失敗也不會被加入黑名單
SDWebImageLowPriority = 1 << 1, 默認(rèn)情況下,在 UI 交互時也會啟動圖像下載, 當(dāng)時用這個標(biāo)記時, 用戶拖動tableView時不會進(jìn)行圖片的下載,當(dāng)沒有交互時才會下載
SDWebImageCacheMemoryOnly = 1 << 2, 此標(biāo)記取消磁盤緩存,僅做內(nèi)存緩存
SDWebImageProgressiveDownload = 1 << 3, 默認(rèn)情況下矮嫉,圖像會在下載完成后一次性顯示, 此標(biāo)記允許漸進(jìn)式下載,就像瀏覽器中那樣,下載過程中芽世,圖像會逐步顯示出來
SDWebImageRefreshCached = 1 << 4, 磁盤緩存將由 NSURLCache 處理,而不是 SDWebImage诡壁,這會對性能有輕微的影響, 此選項有助于處理同一個請求 URL 的圖像發(fā)生變化, 如果緩存的圖像被刷新济瓢,會調(diào)用一次 completion block,并傳遞最終的圖像, 僅在無法使用嵌入式緩存清理參數(shù)確定圖像 URL 時妹卿,使用此標(biāo)記
SDWebImageContinueInBackground = 1 << 5, 在 iOS 4+旺矾,當(dāng) App 進(jìn)入后臺后仍然會繼續(xù)下載圖像。這是向系統(tǒng)請求額外的后臺時間以保證下載請求完成的, 如果后臺任務(wù)過期夺克,請求將會被取消
SDWebImageHandleCookies = 1 << 6, 處理保存在 NSHTTPCookieStore 中的 cookies
SDWebImageAllowInvalidSSLCertificates = 1 << 7, 允許不信任的 SSL 證書, 可以出于測試目的使用箕宙,在正式產(chǎn)品中慎用
SDWebImageHighPriority = 1 << 8, 默認(rèn)情況下,圖像會按照在隊列中的順序被加載懊直,此標(biāo)記會將它們移動到隊列前部立即被加載, 而不是等待當(dāng)前隊列被加載扒吁,等待隊列加載會需要一段時間
SDWebImageDelayPlaceholder = 1 << 9, 默認(rèn)情況下,在加載圖像時室囊,占位圖像已經(jīng)會被加載雕崩。而此標(biāo)記會延遲加載占位圖像,直到圖像已經(jīng)完成加載
SDWebImageTransformAnimatedImage = 1 << 10, 通常不會在可動畫的圖像上調(diào)用 transformDownloadedImage 代理方法融撞,因為大多數(shù)轉(zhuǎn)換代碼會破壞動畫文件, 使用此標(biāo)記嘗試轉(zhuǎn)換
以最為常用的UIImageView為例:
UIImageView+WebCache
分類里面常用的方法:
setImageWithURL :placeholderImage: options:```
這個方法默認(rèn)情況下先顯示 `placeholderImage` 盼铁,同時由`SDWebImageManager `根據(jù) URL 來在本地查找圖片。
SDWebImageManager: downloadWithURL:delegate:options:userInfo:```
SDWebImageManager
是將UIImageView+WebCache
同SDImageCache
鏈接起來的類尝偎,圖片緩存是在內(nèi)存緩存一份,在磁盤緩存一份.
SDImageCache: queryDiskCacheForKey:delegate:userInfo:
用來從緩存根據(jù)CacheKey
查找圖片是否已經(jīng)在內(nèi)存緩存中,如果內(nèi)存中已經(jīng)有圖片緩存饶火,SDWebImageManager
會回調(diào)
SDImageCacheDelegate : imageCache:didFindImage:forKey:userInfo:
而UIImageView+WebCache
則回調(diào)
SDWebImageManagerDelegate: webImageManager:didFinishWithImage:```
來顯示圖片。
如果內(nèi)存中沒有圖片緩存致扯,那么生成 `NSInvocationOperation `添加到隊列肤寝,從硬盤查找圖片是否已被下載緩存。根據(jù)` URLKey` 在硬盤緩存目錄下嘗試讀取圖片文件抖僵。這一步是在 NSOperation 進(jìn)行的操作鲤看,所以回主線程進(jìn)行結(jié)果回調(diào) notifyDelegate:。
如果上一操作從硬盤讀取到了圖片耍群,將圖片添加到內(nèi)存緩存中(如果空閑內(nèi)存過小义桂,會先清空內(nèi)存緩存)找筝。然后`SDImageCacheDelegate `回調(diào)
imageCache:didFindImage:forKey:userInfo:
。進(jìn)而回調(diào)展示圖片慷吊。
如果從硬盤緩存目錄沒有讀取到圖片,說明所有緩存都不存在該圖片袖裕,需要下載圖片,回調(diào)
imageCache:didNotFindImageForKey:userInfo:溉瓶。
共享或重新生成一個下載器 `SDWebImageDownloader` 開始下載圖片急鳄。
圖片下載由` NSURLConnection `來做,實現(xiàn)相關(guān) delegate 來判斷圖片下載中嚷闭、下載完成和下載失敗攒岛。
```connection:didReceiveData: ```
中利用 ` ImageIO ` 做了按圖片下載進(jìn)度加載效果。
`connectionDidFinishLoading: `數(shù)據(jù)下載完成后交給 `SDWebImageDecoder` 做圖片解碼處理胞锰。
圖片解碼處理在一個 `NSOperationQueue` 完成灾锯,不會拖慢主線程 UI。如果有需要對下載的圖片進(jìn)行二次處理嗅榕,最好也在這里完成顺饮,效率會好很多。
在主線程
notifyDelegateOnMainThreadWithInfo:
宣告解碼完成凌那,
imageDecoder:didFinishDecodingImage:userInfo:
回調(diào)給 `SDWebImageDownloader`兼雄。
imageDownloader:didFinishWithImage: 回調(diào)給 `SDWebImageManager `告知圖片下載完成。
通知所有的 `downloadDelegates` 下載完成帽蝶,回調(diào)給需要的地方展示圖片赦肋。
將圖片保存到 `SDImageCache `中,內(nèi)存緩存和磁盤緩存同時進(jìn)行保存励稳。
寫文件到磁盤在單獨 `NSInvocationOperation `中完成佃乘,避免拖慢主線程。
如果是在iOS上運(yùn)行驹尼,`SDImageCache` 在初始化的時候會注冊`notification` 到
UIApplicationDidReceiveMemoryWarningNotification
以及` UIApplicationWillTerminateNotification`,在內(nèi)存警告的時候清理內(nèi)存圖片緩存趣避,應(yīng)用結(jié)束的時候清理過期圖片。
`SDWebImagePrefetcher `可以預(yù)先下載圖片新翎,方便后續(xù)使用程帕。
下面是`SDWebImage`在清理圖片緩存時的原理
####使用SDWebImage設(shè)置cell圖片(網(wǎng)上下載)的注意點
當(dāng)程序收到內(nèi)存警告的時候就會調(diào)用下面的方法
![screenshot.png](http://upload-images.jianshu.io/upload_images/788734-08ba5945858af31e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
####SDWebImage在cleanMemary(清除緩存)時的運(yùn)行原理
- 遍歷緩存目錄,刪除所有過期圖片
- 統(tǒng)計沒有過期的圖片的總大小
- 判斷沒有過期的圖片的總大小是否超過了最大的緩存大小
- 如果過期圖片超過緩存總大小就會繼續(xù)刪除沒有過期的圖片,從大到小的刪除