SDWebImage
是用于加載服務(wù)器圖片庫浙于,對UIkit做了二次封裝
一港令、SDWebImage的加載流程
-
setImageWithURL:placeholderImage:options:
會先把placeholderImage
顯示. -
SDWebImageManager
根據(jù) URL 通過集畅。SDWebImageManager-downloadWithURL:delegate:options:userInfo:
,交給SDImageCache
從內(nèi)存內(nèi)存緩存
查找是否有圖片讥珍,如果內(nèi)存中已經(jīng)有圖片緩存徙融,SDImageCacheDelegate
回調(diào)imageCache:didFindImage:forKey:userInfo:
到SDWebImageManager
。 - 如果內(nèi)存緩存中沒有哭靖,生成
NSInvocationOperation
添加到隊列開始從硬盤緩存
查找圖片是否已經(jīng)緩存具垫。根據(jù)URLKey
在硬盤緩存目錄下嘗試讀取圖片文件。這一步是在NSOperation
進行的操作试幽,所以回主線程進行結(jié)果回調(diào)notifyDelegate:
筝蚕。 - 如果從硬盤緩存中查到了圖片,則將圖片添加到內(nèi)存緩存中
(如果空閑內(nèi)存過小铺坞,會先清空內(nèi)存緩存)
起宽,進而回調(diào)展示圖片。 - 如果從緩存中找不到圖片济榨,執(zhí)行回調(diào)方法
imageCache:didNotFindImageForKey:userInfo:燎含。
- 共享或重新生成一個下載器
SDWebImageDownloader
開始下載圖片。數(shù)據(jù)下載完成后交給SDWebImageDecoder
做圖片解碼處理腿短。 - 圖片解碼處理在一個 NSOperationQueue 完成屏箍,不會拖慢主線程 UI。如果有需要對下載的圖片進行二次處理橘忱,最好也在這里完成赴魁,效率會好很多。
- 在主線程
notifyDelegateOnMainThreadWithInfo
: 宣告解碼完成钝诚,imageDecoder:didFinishDecodingImage:userInfo:
回調(diào)給SDWebImageDownloader
颖御。imageDownloader:didFinishWithImage:
回調(diào)給SDWebImageManager
告知圖片下載完成。 - 通知所有的
downloadDelegates
下載完成,回調(diào)給需要的地方展示圖片潘拱。將圖片保存到SDImageCache
中疹鳄,內(nèi)存緩存和硬盤緩存同時保存。寫文件到硬盤也在以單獨NSInvocationOperation
完成芦岂,避免拖慢主線程瘪弓。 -
SDImageCache
在初始化的時候會注冊一些消息通知,在內(nèi)存警告或退到后臺的時候
清理內(nèi)存圖片緩存禽最,應(yīng)用結(jié)束的時候清理過期圖片腺怯。
一、SDWebImage的圖片緩存
圖片下載完成后川无,SDWebImage
提供了對圖片進行了緩存呛占,主要由SDImageCache
完成。該類負責(zé)處理內(nèi)存緩存以及一個可選的磁盤緩存懦趋,其中磁盤緩存的寫操作是異步的晾虑,不會對UI造成影響。
SDImageCache
是繼承自NSCache仅叫,之所以繼承走贪,是因為NSCache
是系統(tǒng)管理的,開發(fā)者不能去管理緩存
圖片緩存分為內(nèi)存緩存和磁盤緩存
1.內(nèi)存緩存的處理由NSCache對象實現(xiàn)惑芭,NSCache類似一個集合的容器坠狡,它存儲key-value對,類似于nsdictionary類遂跟,我們通常使用緩存來臨時存儲短時間使用但創(chuàng)建昂貴的對象逃沿,重用這些對象可以優(yōu)化新能,同時這些對象對于程序來說不是緊要的幻锁,如果內(nèi)存緊張就會自動釋放凯亮。
2.磁盤緩存的處理使用NSFileManager
對象實現(xiàn),圖片存儲的位置位于cache
文件夾哄尔,另外SDImageCache
還定義了一個串行隊列來異步存儲圖片假消。
3.SDImageCache提供了大量方法來緩存、獲取岭接、移除及清空圖片富拗。對于圖片的索引,我們通過一個key來索引鸣戴,在內(nèi)存中啃沪,我們將其作為NSCache的key值,而在磁盤中窄锅,我們用這個key值作為圖片的文件名创千,對于一個遠程下載的圖片其url實作為這個key的最佳選擇。
2、存儲圖片
先在內(nèi)存中放置一份緩存追驴,如果需要緩存到磁盤械哟,將磁盤緩存操作作為一個task放到串行隊列中處理,會先檢查圖片格式是jpeg還是png殿雪,將其轉(zhuǎn)換為響應(yīng)的圖片數(shù)據(jù)宿饱,最后吧數(shù)據(jù)寫入磁盤中(文件名是對key值做MD5后的串)爹橱。
3染苛、查詢圖片
內(nèi)存和磁盤查詢圖片API:
- (UIImage *)imageFromMemoryCacheForKey:(NSString *)key;
- (UIImage *)imageFromDiskCacheForKey:(NSString *)key;
查看本地是否存在key指定的圖片拓哟,使用一下API:
- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock;
4几缭、移除圖片
移除圖片API:
- (void)removeImageForKey:(NSString *)key;
- (void)removeImageForKey:(NSString *)key withCompletion:(SDWebImageNoParamsBlock)completion;
- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk;
- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(SDWebImageNoParamsBlock)completion;
5河泳、清理圖片(磁盤)
清空磁盤圖片可以選擇完全清空和部分清空,完全清空就是吧緩存文件夾刪除年栓。
- (void)clearDisk;
- (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion;
部分清理 會根據(jù)設(shè)置的一些參數(shù)移除部分文件拆挥,主要有兩個指標(biāo):文件的緩存有效期(maxCacheAge:默認是1周)和最大緩存空間大小(maxCacheSize:如果所有文件大小大于最大值某抓,會按照文件最后修改時間的逆序纸兔,以每次一半的遞歸來移除哪些過早的文件,知道緩存文件總大小小于最大值)否副,具體代碼參考- (void)cleanDiskWithCompletionBlock汉矿;
6、小結(jié)
SDImageCache處理提供以上API备禀,還提供了獲取緩存大小洲拇,緩存中圖片數(shù)量等API,
常用的接口和屬性:
(1)-getSize :獲得硬盤緩存的大小
(2)-getDiskCount : 獲得硬盤緩存的圖片數(shù)量
(3)-clearMemory : 清理所有內(nèi)存圖片
(4)- removeImageForKey:(NSString *)key 系列的方法 : 從內(nèi)存曲尸、硬盤按要求指定清除圖片
(5)maxMemoryCost : 保存在存儲器中像素的總和
(6)maxCacheSize : 最大緩存大小 以字節(jié)為單位赋续。默認沒有設(shè)置,也就是為0另患,而清理磁盤緩存的先決條件為self.maxCacheSize > 0纽乱,所以0表示無限制。
(7)maxCacheAge : 在內(nèi)存緩存保留的最長時間以秒為單位計算昆箕,默認是一周
一鸦列、SDWebImage的圖片下載
- SDWebImageDownloader圖片下載器,負責(zé)圖片異步下載鹏倘,并對圖片加載做了優(yōu)化處理
- 圖片的下載操作放在一個
NSOperationQueue
并發(fā)操作隊列中敛熬,隊列默認最大并發(fā)數(shù)是6 - 每個圖片對應(yīng)一些回調(diào)(下載進度,完成回調(diào)等)第股,回調(diào)信息會存在
downloader的URLCallbacks
(一個字典应民,key是url地址,value是圖片下載回調(diào)數(shù)組)中,URLCallbacks
可能被多個線程訪問诲锹,所以downloader
把下載任務(wù)放在一個barrierQueue
中繁仁,并設(shè)置屏障保證同一時間只有一個線程訪問URLCallbacks
。在創(chuàng)建回調(diào)URLCallbacks的block
中創(chuàng)建了一個NSOperation
并添加到NSOperationQueue
中归园。 - 每個圖片下載都是一個
operation
類黄虱,創(chuàng)建后添加到一個隊列中,SDWebimage
定義了一個協(xié)議SDWebImageOperation
作為圖片下載操作的基礎(chǔ)協(xié)議庸诱,聲明了一個cancel
方法捻浦,用于取消操作。
@protocol SDWebImageOperation <NSObject>
-(void)cancel;
@end
- 對于圖片的下載桥爽,
SDWebImageDownloaderOperation
完全依賴于NSURLConnection
類朱灿,繼承和實現(xiàn)了NSURLConnectionDataDelegate協(xié)議的方法
connection:didReceiveResponse:
connection:didReceiveData:
connectionDidFinishLoading:
connection:didFailWithError:
connection:willCacheResponse:
connectionShouldUseCredentialStorage:
-connection:willSendRequestForAuthenticationChalleng
-connection:didReceiveData:方法,接受數(shù)據(jù)钠四,創(chuàng)建一個CGImageSourceRef對象盗扒,在首次獲取數(shù)據(jù)時(圖片width,height)缀去,圖片下載完成之前侣灶,使用CGImageSourceRef對象創(chuàng)建一個圖片對象,經(jīng)過縮放缕碎、解壓操作生成一個UIImage對象供回調(diào)使用褥影,同時還有下載進度處理。
注:縮放:SDWebImageCompat中SDScaledImageForKey函數(shù)
解壓:SDWebImageDecoder文件中decodedImageWithImage
SDWebImageDownloaderOption
1.繼承自NSOperation
類咏雌,沒有簡單實現(xiàn)main
方法凡怎,而是采用更加靈活的start
方法,以便自己管理下載的狀態(tài)
2.start方法中創(chuàng)建了下載使用的NSURLConnections
對象处嫌,開啟了圖片的下載栅贴,并拋出一個下載開始的通知,
3.小結(jié):下載的核心是利用NSURLSession
加載數(shù)據(jù)熏迹,每個圖片的下載都有一個operation
操作來完成檐薯,并將這些操作放到一個操作隊列中,這樣可以實現(xiàn)圖片的并發(fā)下載注暗。
SDWebImageDecoder
(異步對圖片進行解碼)