上一遍博客我們提到了 SDWebImage 的一些使用,這篇我們來講解一下具體運用時的語法
SDWebImage 提供一個UIImageView類別以支持加載來自網(wǎng)絡(luò)的遠程圖片密任。具有緩存管理、異步下載、同一個URL下載次數(shù)控制和優(yōu)化等特征啥刻。
SDWebImage 支持異步的圖片下載+緩存掌实,提供了 UIImageView+WebCacha 的 category,方便使用。紀錄一下 SDWebImage 加載圖片的流程栓撞。
1. sd_setImageWithURL:
[self.image1 sd_setImageWithURL:imagePath1];
2. sd_setImageWithURL:? completed:
//用block 可以在圖片加載完成之后做些事情
[self.image2 sd_setImageWithURL:imagePath2 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
NSLog(@"這里可以在圖片加載完成之后做些事情");
}];
3. sd_setImageWithURL:? placeholderImage:
//給一張默認圖片纪隙,先使用默認圖片赊豌,當圖片加載完成后再替換
[self.image1 sd_setImageWithURL:imagePath1 placeholderImage:[UIImage imageNamed:@"abc.jpeg"]];
4. sd_setImageWithURL:? placeholderImage:? completed:
//使用默認圖片,而且用block 在完成后做一些事情
[self.image1 sd_setImageWithURL:imagePath1 placeholderImage:[UIImage imageNamed:@"abc.jpeg"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
NSLog(@"圖片加載完成后做的事情");
}];
5. sd_setImageWithURL:? placeholderImage:? options:
//options 選擇方式
[self.image1 sd_setImageWithURL:imagePath1 placeholderImage:[UIImage imageNamed:@"abc.jpeg"] options:SDWebImageRetryFailed];
下面我們來看一下 ?SDWebImage 內(nèi)部的實現(xiàn)過程
入口 setImageWithURL:placeholderImage:options: 會先把 placeholderImage 顯示绵咱,然后 SDWebImageManager 根據(jù) URL 開始處理圖片碘饼。
進入 SDWebImageManager-downloadWithURL:delegate:options:userInfo:,交給 SDImageCache 從緩存查找圖片是否已經(jīng)下載 queryDiskCacheForKey:delegate:userInfo:.
先從內(nèi)存圖片緩存查找是否有圖片悲伶,如果內(nèi)存中已經(jīng)有圖片緩存艾恼,SDImageCacheDelegate 回調(diào) imageCache:didFindImage:forKey:userInfo: 到 SDWebImageManager。
SDWebImageManagerDelegate 回調(diào) webImageManager:didFinishWithImage: 到 UIImageView+WebCache 等前端展示圖片拢切。
如果內(nèi)存緩存中沒有蒂萎,生成 NSInvocationOperation 添加到隊列開始從硬盤查找圖片是否已經(jīng)緩存。
根據(jù) URLKey 在硬盤緩存目錄下嘗試讀取圖片文件淮椰。這一步是在 NSOperation 進行的操作五慈,所以回主線程進行結(jié)果回調(diào) notifyDelegate:。
如果上一操作從硬盤讀取到了圖片主穗,將圖片添加到內(nèi)存緩存中(如果空閑內(nèi)存過小泻拦,會先清空內(nèi)存緩存)。SDImageCacheDelegate 回調(diào) imageCache:didFindImage:forKey:userInfo:忽媒。進而回調(diào)展示圖片争拐。
如果從硬盤緩存目錄讀取不到圖片,說明所有緩存都不存在該圖片晦雨,需要下載圖片架曹,回調(diào) imageCache:didNotFindImageForKey:userInfo:隘冲。
共享或重新生成一個下載器 SDWebImageDownloader 開始下載圖片。
圖片下載由 NSURLConnection 來做绑雄,實現(xiàn)相關(guān) delegate 來判斷圖片下載中展辞、下載完成和下載失敗。
connection:didReceiveData: 中利用 ImageIO 做了按圖片下載進度加載效果万牺。
connectionDidFinishLoading: 數(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é)束的時候清理過期圖片膜楷。
SDWI 也提供了 UIButton+WebCache 和 MKAnnotationView+WebCache旭咽,方便使用。
SDWebImagePrefetcher 可以預(yù)先下載圖片赌厅,方便后續(xù)使用穷绵。
獨立的異步圖像下載
可能會單獨用到異步圖片下載,則一定要用downloaderWithURL:delegate:來建立一個SDWebImageDownloader實例特愿。
downloader = [SDWebImageDownloader downloaderWithURL:url delegate:self];
這樣SDWebImageDownloaderDelegate協(xié)議的方法imageDownloader:didFinishWithImage:被調(diào)用時下載會立即開始并完成仲墨。
獨立的異步圖像緩存
SDImageCache類提供一個創(chuàng)建空緩存的實例,并用方法imageForKey:來尋找當前緩存揍障。
UIImage *myCachedImage = [[SDImageCache sharedImageCache] imageFromKey:myCacheKey];
存儲一個圖像到緩存是使用方法storeImage: forKey:
[[SDImageCache sharedImageCache] storeImage:myImage forKey:myCacheKey];
默認情況下目养,圖像將被存儲在內(nèi)存緩存和磁盤緩存中。如果僅僅是想內(nèi)存緩存中毒嫡,要使用storeImage:forKey:toDisk:方法的第三個參數(shù)帶一負值
來替代癌蚁。