標籤:c code http a int com
本文轉載值至:http://www.overcode.hk/?p=449
SDWebImage是一個很厲害的圖片緩衝的架構。既ASIHttp+AsyncImage之後,我一直使用AFNetworking整合的UIImageView+AFNetworking.h,但後者對於圖片的緩衝實際應用的是NSURLCache內建的cache機制。而NSURLCache每次都要把緩衝的raw data 再轉化為UIImage,就帶來了資料處理和記憶體方面的更多操作。具體的比較在這裡。
SDWebImage提供了如下三個category來進行緩衝。
- MKAnnotationView(WebCache)
- UIButton(WebCache)
- UIImageView(WebCache)
以最為常用的UIImageView為例:
- UIImageView+WebCache:
setImageWithURL:placeholderImage:options: 先顯示 placeholderImage ,同時由SDWebImageManager 根據 URL 來在本地尋找圖片。
- SDWebImageManager:
downloadWithURL:delegate:options:userInfo: SDWebImageManager是將UIImageView+WebCache同SDImageCache連結起來的類, SDImageCache: queryDiskCacheForKey:delegate:userInfo:用來從緩衝根據CacheKey尋找圖片是否已經在緩衝中
- 如果記憶體中已經有圖片緩衝, SDWebImageManager會回調SDImageCacheDelegate :
imageCache:didFindImage:forKey:userInfo:
- 而 UIImageView+WebCache 則回調SDWebImageManagerDelegate:
webImageManager:didFinishWithImage:來顯示圖片。
- 如果記憶體中沒有圖片緩衝,那麼產生 NSInvocationOperation 添加到隊列,從硬碟尋找圖片是否已被下載快取。
- 根據 URLKey 在硬碟緩衝目錄下嘗試讀取圖片檔案。這一步是在 NSOperation 進行的操作,所以回主線程進行結果回調
notifyDelegate:。
- 如果上一操作從硬碟讀取到了圖片,將圖片添加到記憶體緩衝中(如果空閑記憶體過小,會先清空記憶體緩衝)。SDImageCacheDelegate 回調
imageCache:didFindImage:forKey:userInfo:。進而回調展示圖片。
- 如果從硬碟緩衝目錄讀取不到圖片,說明所有緩衝都不存在該圖片,需要下載圖片,回調
imageCache:didNotFindImageForKey:userInfo:。
- 共用或重建一個下載器
SDWebImageDownloader 開始下載圖片。
- 圖片下載由 NSURLConnection 來做,實現相關 delegate 來判斷圖片下載中、下載完成和下載失敗。
connection:didReceiveData: 中利用 ImageIO 做了按圖片下載進度載入效果。
connectionDidFinishLoading: 資料下載完成後交給 SDWebImageDecoder 做圖片解碼處理。
- 圖片解碼處理在一個 NSOperationQueue 完成,不會拖慢主線程 UI。如果有需要對下載的圖片進行二次處理,最好也在這裡完成,效率會好很多。
- 在主線程
notifyDelegateOnMainThreadWithInfo: 宣告解碼完成,imageDecoder:didFinishDecodingImage:userInfo: 回調給 SDWebImageDownloader。
imageDownloader:didFinishWithImage: 回調給 SDWebImageManager 告知圖片下載完成。
- 通知所有的 downloadDelegates 下載完成,回調給需要的地方展示圖片。
- 將圖片儲存到 SDImageCache 中,記憶體緩衝和硬碟緩衝同時儲存。
- 寫檔案到硬碟在單獨 NSInvocationOperation 中完成,避免拖慢主線程。
- 如果是在iOS上運行,SDImageCache 在初始化的時候會註冊notification 到 UIApplicationDidReceiveMemoryWarningNotification 以及 UIApplicationWillTerminateNotification,在記憶體警告的時候清理記憶體配置圖片緩衝,應用結束的時候清理到期圖片。
SDWebImagePrefetcher 可以預先下載圖片,方便後續使用。