SDWebImage緩存圖片的機制
SDWebImage是一個很厲害的圖片緩存的框架。既ASIHttp+AsyncImage之后,我一直使用AFNetworking集成的UIImageView+AFNetworking.h,但后者對于圖片的緩存實際應用的是NSURLCache自帶的cache機制。而NSURLCache每次都要把緩存的raw data 再轉化為UIImage,就帶來了數據處理和內存方面的更多操作。具體的比較在這里。
SDWebImage提供了如下三個category來進行緩存。
以最為常用的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可以預先下載圖片,方便后續使用。
轉:http://www.overcode.hk/?p=449
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!