在 iOS 的圖片加載框架中,SDWebImage 可謂是占據(jù)大半壁江山谅阿。它支持從網(wǎng)絡中下載且緩存圖片琴昆,并設置圖片到對應的 UIImageView 控件或者 UIButton 控件。在項目中使用 SDWebImage 來管理圖片加載相關(guān)操作可以極大地提高開發(fā)效率,讓我們更加專注于業(yè)務邏輯實現(xiàn)蘑斧。
SDWebImage 概論
1.提供了一個 UIImageView 的 category 用來加載網(wǎng)絡圖片并且對網(wǎng)絡圖片的緩存進行管理
2.采用異步方式來下載網(wǎng)絡圖片
3.采用異步方式,使用 memory+disk 來緩存網(wǎng)絡圖片,自動管理緩存份殿。
4.支持 GIF 動畫
5.支持 WebP 格式
6.同一個 URL 的網(wǎng)絡圖片不會被重復下載
7.失效的 URL 不會被無限重試
8.耗時操作都在子線程,確保不會阻塞主線程
9.使用 GCD 和 ARC
10.支持 Arm64
SDWebImage 使用
1.使用 ImageView+WebCache category 來加載 UITableView 中 cell 的圖片
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
2.使用 block,采用這個方案可以在網(wǎng)絡圖片加載過程中得知圖片的下載進度和圖片加載成功與否
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
//... completion code here ...
}];
3.使用 SDWebImageManager,SDWebImageManager 為UIImageView+WebCache category 的實現(xiàn)提供接口嗽交。
SDWebImageManager *manager = [SDWebImageManager sharedManager] ;
[manager downloadImageWithURL:imageURL options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
// progression tracking code
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (image) {
// do something with image
}
}];
4.加載圖片還有使用 SDWebImageDownloader 和 SDImageCache 方式伯铣,但那個并不是我們經(jīng)常用到的÷秩遥基本上面所講的3個方法都能滿足需求腔寡。
SDWebImage 流程
SDWebImage 接口
SDWebImage 是一個成熟而且比較龐大的框架,但是在使用過程中并不需要太多的接口,這算是一種代碼封裝程度的體現(xiàn)掌唾。這里就介紹比較常用的幾個接口放前。
-
給 UIImageView 設置圖片的接口,SDWebImage 有提供多個給UIImageView 設置圖片的接口糯彬,最終所有的接口都會調(diào)用下圖的這個接口凭语,這是大多數(shù)框架的做法。
獲取 SDWebImage 的磁盤緩存大小,在項目中有時候會需要統(tǒng)計應用的磁盤緩存內(nèi)容大小撩扒,那么獲取圖片的緩存大小就是使用這個接口來實現(xiàn)
[SDImageCache sharedImageCache] getSize];
- 清理內(nèi)存緩存似扔,清理內(nèi)存中緩存的圖片資源吨些,釋放內(nèi)存資源。
[[SDImageCache sharedImageCache] clearMemory];
- 有了清理內(nèi)存緩存炒辉,自然也有清理磁盤緩存的接口
[[SDImageCache sharedImageCache] clearDisk];
SDWebImage 解析
解析主要圍繞著 SDWebImage 的圖片加載流程來分析豪墅,介紹SDWebImage 這個框架加載圖片過程中的一些處理方法和設計思路。
-
給 UIImageView 設置圖片黔寇,然后 SDWebImage 調(diào)用這個最終的圖片加載方法偶器。
開始加載之前圖片先取消對應的 UIImageView 先前的圖片下載操作。試想缝裤,如果我們給 UIImageView 設置了一張新的圖片屏轰,那么我們還會在意該 UIImageVIew 先前是要加載哪一張圖片么?應該是不在意的吧憋飞!那是不是應該嘗試把該 UIImageView 先前的加載圖片相關(guān)操作給取消掉呢?
[self sd_cancelCurrentImageLoad]
該方法經(jīng)過周轉(zhuǎn)霎苗,最后調(diào)用了以下方法,框架將圖片對應的下載操作放到 UIView 的一個自定義字典屬性 (operationDictionary) 中榛做,取消下載操作第一步也是從這個 UIView 的自定義字典屬性 (operationDictionary)中取出所有的下載操作叨粘,然后依次調(diào)用取消方法,最后將取消的操作從(operationDictionary) 字典屬性中移除瘤睹。
3.移除之前沒用的圖片下載操作之后就創(chuàng)建一個新的圖片下載操作升敲,然后設置到 UIView 的一個自定義字典屬性 (operationDictionary) 中。
4.看看如何創(chuàng)建一個新的圖片下載操作,框架保存了一個失效的 url 列表轰传,如果 url 失效了就會被加入這個列表驴党,保證不會重復多次請求失效的 url。
根據(jù)給定的 url 生成一個唯一的 key ,之后利用這個 key 到緩存中查找對應的圖片緩存获茬。
5.讀取圖片緩存,根據(jù) key 先從內(nèi)存中讀取圖片緩存港庄,若沒有命中內(nèi)存緩存則讀取磁盤緩存,如果磁盤緩存命中恕曲,那么將磁盤緩存讀到內(nèi)存中成為內(nèi)存緩存鹏氧。如果都沒有命中緩存的話,那么就在執(zhí)行的 doneBlock中開始下載圖片佩谣。
6.圖片下載操作完成后會將圖片對應的數(shù)據(jù)通過 completedBlock 進行回調(diào)
在圖片下載方法中把还,調(diào)用了一個方法用于添加創(chuàng)建和下載過程中的各類block 回調(diào)。
添加該 url 加載過程的狀態(tài)回調(diào) block
如果該 url 是第一次加載的話茸俭,那么就會執(zhí)行 createCallback 這個回調(diào)block ,然后在 createCallback 里面開始構(gòu)建網(wǎng)絡請求吊履,在下載過程中執(zhí)行各類進度 block 回調(diào)。
7.當圖片下載完成之后會回到 done 的 block 回調(diào)中做圖片轉(zhuǎn)換處理和緩存操作
回到 UIImageView 控件的設置圖片方法 block 回調(diào)中调鬓,給對應的UIImageView 設置圖片艇炎,操作流程到此完成。
8.304 的處理
SDWebImage在加載圖片網(wǎng)絡請求的 NSURLConnection 的代理中對httpCode 做了判斷腾窝,當 httpCode 為 304 的時候放棄下載缀踪,讀取緩存居砖。
總結(jié)
SDWebImage 作為一個優(yōu)秀的圖片加載框架,提供的使用方法和接口對開發(fā)者來說非常友好驴娃。其內(nèi)部實現(xiàn)多是采用 block 的方式來實現(xiàn)回調(diào)奏候,代碼閱讀起來可能沒有那么直觀。此文章旨在給大家講解 SDWebImage 這個框架的圖片大概加載流程托慨,其中具體細節(jié)限于篇幅無法詳細深究鼻由。能力有限暇榴,文章中難免有錯誤厚棵,若大家在閱讀過程中有發(fā)現(xiàn)不合理或者錯誤的地方懇請在評論中指出,我會在第一時間進行修正,不勝感激蔼紧。