SDWebImage是咱們在平常開發中經常使用的一個圖片加載庫。它都有什麼功能呢?前端
1.一個添加了web圖片加載和緩存管理的UIImageView分類;web
2.一個異步圖片下載器;面試
3.一個異步的內存加磁盤綜合存儲圖片而且自動處理過時圖片;數組
4.支持動態gif圖;緩存
5.支持webP格式的圖片;網絡
6後天圖片解壓處理;app
7.確保一樣的圖片url不會下載屢次;異步
8.確保僞造的圖片url不會重複嘗試下載;fetch
9.確保主線程不會阻塞動畫
基本使用:
// 經常使用簡單設置 [cell.imageView sd_setImageWithURL:[NSURL URLWithString:app.icon] placeholderImage:[UIImage imageNamed:@"placehoder"]]; // 設置圖片並計算下載進度 /* 第一個參數:要下載圖片的url地址 第二個參數:設置該imageView的佔位圖片 第三個參數:傳一個枚舉值,告訴程序你下載圖片的策略是什麼 第一個block塊:獲取當前圖片數據的下載進度 receivedSize:已經下載完成的數據大小 expectedSize:該文件的數據總大小 第二個block塊:當圖片下載完成以後執行該block中的代碼 image:下載獲得的圖片數據 error:下載出現的錯誤信息 SDImageCacheType:圖片的緩存策略(不緩存,內存緩存,沙盒緩存) imageURL:下載的圖片的url地址 */ [cell.imageView sd_setImageWithURL:[NSURL URLWithString:app.icon] placeholderImage:[UIImage imageNamed:@"placehoder"] options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize) { //計算當前圖片的下載進度 NSLog(@"%.2f",1.0 *receivedSize / expectedSize); } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { }];
// 系統級內存警告如何處理(面試重點) //取消當前正在進行的全部下載操做 [[SDWebImageManager sharedManager] cancelAll]; //清除緩存數據 //cleanDisk:刪除過時的文件數據,計算當前未過時的已經下載的文件數據的大小,若是發現該數據大小大於咱們設置的最大緩存數據大小,那麼程序內部會按照按文件數據緩存的時間從遠到近刪除,知道小於最大緩存數據爲止。 //clearMemory:直接刪除文件,從新建立新的文件夾 [[SDWebImageManager sharedManager].imageCache cleanDisk]; [[SDWebImageManager sharedManager].imageCache clearMemory]; // SDWebImage默認緩存時間是一週 // 如何播放Gif圖片 /* 1 把用戶傳入的gif圖片->NSData 2 根據該Data建立一個圖片數據源(NSData->CFImageSourceRef) 3 計算該數據源中一共有多少幀,把每一幀數據取出來放到圖片數組中 4 根據獲得的數組+計算的動畫時間-》可動畫的image [UIImage animatedImageWithImages:images duration:duration]; */
// 如何判斷當前圖片類型,只判斷圖片二進制數據的第一個字節 + (NSString *)sd_contentTypeForImageData:(NSData *)data; // 內部如何進行緩存處理? // 使用了NSCache類,使用和NSDictionary相似 // 沙盒緩存圖片的命名方式爲對該圖片的URL進行MD5加密 echo -n "url" |MD5 // 當接收到內存警告以後,內部會自動清理內存緩存 // 圖片的下載順序,默認是先進先出的
內部結構
加載圖片流程
1.入口方法 setImageWithURL :placeholderImage: options: 這個方法默認狀況下先顯示 placeholderImage ,同時由SDWebImageManager根據 URL 來在本地查找圖片。 2.進入方法 SDWebImageManager: downloadWithURL:delegate:options:userInfo: SDWebImageManager是將UIImageView+WebCache同SDImageCache連接起來的類,圖片緩存是在內存緩存一份,在磁盤緩存一份. SDImageCache: queryDiskCacheForKey:delegate:userInfo: 用來(根據CacheKey)查找圖片是否已經在內存緩存中 3.首先在緩存中查找。若是內存中已經有圖片緩存,SDWebImageManager會回調 SDImageCacheDelegate : imageCache:didFindImage:forKey:userInfo: 4.而UIImageView+WebCache則回調 SDWebImageManagerDelegate: webImageManager:didFinishWithImage:前端來顯示圖片。 5.若是內存中沒有圖片緩存,那麼生成 NSInvocationOperation添加到隊列,從硬盤查找圖片是否已被下載緩存。 6.根據URLKey 在硬盤緩存目錄下嘗試讀取圖片文件。這一步是在 NSOperation 進行的操做,因此回主線程進行結果回調 notifyDelegate:。
7.若是上一操做從硬盤讀取到了圖片,將圖片添加到內存緩存中(若是空閒內存太小,會先清空內存緩存)。而後SDImageCacheDelegate回調 imageCache:didFindImage:forKey:userInfo:。進而回調展現圖片。 8.若是從硬盤緩存目錄沒有讀取到圖片,說明全部緩存都不存在該圖片,須要下載圖片,回調 imageCache:didNotFindImageForKey:userInfo:。 9.共享或從新生成一個下載器 SDWebImageDownloader 開始下載圖片。圖片下載由NSURLConnection來作,實現相關 delegate 來判斷圖片下載中、下載完成和下載失敗。 10.connection:didReceiveData:中利用 ImageIO 作了按圖片下載進度加載效果。connectionDidFinishLoading:數據下載完成後交給 SDWebImageDecoder 作圖片解碼處理。
11.圖片解碼處理在一個 NSOperationQueue 完成,不會拖慢主線程 UI。若是有須要對下載的圖片進行二次處理,最好也在這裏完成,效率會好不少。 12.在主線程 notifyDelegateOnMainThreadWithInfo:宣告解碼完成,imageDecoder:didFinishDecodingImage:userInfo:回調給 SDWebImageDownloader。imageDownloader:didFinishWithImage: 回調給 SDWebImageManager告知圖片下載完成。 13.通知全部的 downloadDelegates 下載完成,回調給須要的地方展現圖片。 14.將圖片保存到 SDImageCache中,內存緩存和磁盤緩存同時進行保存。寫文件到磁盤在單獨 NSInvocationOperation中完成,避免拖慢主線程。 15.若是是在iOS上運行,SDImageCache 在初始化的時候會註冊notification 到 UIApplicationDidReceiveMemoryWarningNotification以及UIApplicationWillTerminateNotification,在內存警告的時候清理內存圖片緩存,應用結束的時候清理過時圖片。 16.SDWebImagePrefetcher能夠預先下載圖片,方便後續使用。
SDWebImage在清理圖片緩存時的原理:
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { /** *若是接收到內存警告,那麼應該清空內存緩存,而後中止當前全部的下載操做 cleanDisk:清除已通過期的圖片 cleanDisk:刪除緩存目錄中全部的緩存圖片(內部就是刪除了整個文件夾,再從新建立一個) SDWebImage默認的緩存時間是多長:1星期 SDWebImage是如何播放gif圖片的:取出gif中的每一幀圖片,從新生成新的可動畫的圖片 */ [[SDWebImageManager sharedManager].imageCache clearMemory]; // 取消全部的下載 [[SDWebImageManager sharedManager] cancelAll]; }
SDWebImage在cleanMemary(清除緩存)時的運行原理:
遍歷緩存目錄,刪除全部過時圖片
統計沒有過時的圖片的總大小
判斷沒有過時的圖片的總大小是否超過了最大的緩存大小
若是過時圖片超過緩存總大小就會繼續刪除沒有過時的圖片,從大到小的刪除
SDImageCache是怎麼作數據管理的?
SDImageCache分兩個部分,一個是內存層面的,一個是硬盤層面的。 內存層面的至關是個緩存器,以Key-Value的形式存儲圖片。當內存不夠的時候會清除全部緩存圖片。用搜索文件系統的方式作管理,文件替換方式是以時間爲單位,剔除時間大於一週的圖片文件。當SDWebImageManager向SDImageCache要資源時,先搜索內存層面的數據,若是有直接返回,沒有的話去訪問磁盤,將圖片從磁盤讀取出來,而後作Decoder,將圖片對象放到內存層面作備份,再返回調用層 clearDisk (NSCache)清空磁盤緩存,將全部緩存目錄中的文件,所有刪除! 實際工做,將緩存目錄直接刪除,再次建立一個同名空目錄!cleanDisk (接收到應用程序將要終止通知)清理磁盤緩存策略 cleanDisk執行過程: 1.獲取磁盤路徑URL,根據路徑獲取資源(存入NSArray) 2.定義一個可變字典,記錄全部緩存文件 3.定義一個可變數組,遍歷資源,將過時文件記錄到可變數組裏邊,累加文件的總大小,而後遍歷過時文件數組刪除過時文件 4.若是剩餘磁盤緩存空間超出最大限額,再次執行清理操做,刪除最先的文件 循環依次刪除文件,直到低於指望的緩存限額,SDWebimage裏邊的指望限額爲最大限額的一半