在iOS的請求網(wǎng)絡圖片框架中亿乳, [**SDWebImage**](https://github.com/rs/SDWebImage) 可謂是占據(jù)大半壁江山途事。它支持從網(wǎng)絡中下載且緩存圖片后室,并設置圖片到對應的UIImageView控件或者UIButton控件躯护。如在我們熟悉的UITableView中經常使用到:```/** * Integrates SDWebImage async downloading and caching of remote images with UIImageView. * * Usage with a UITableViewCell sub-class: * * @code#import...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
}
// Here we use the provided sd_setImageWithURL: method to load the web image
// Ensure you use a placeholder image otherwise cells will be initialized with no image
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://example.com/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder"]];
cell.textLabel.text = @"My Text";
return cell;
}
* @endcode
*/
```
這樣簡單方便地在項目中使用SDWebImage來管理圖片加載相關操作本股,可以極大地提高開發(fā)效率攀痊,讓我們更加專注于業(yè)務邏輯實現(xiàn)。趁最近項目不忙拄显,我閑下來研究其實現(xiàn)的過程苟径,多讀源碼,更有助于提高自己的編碼水平吧躬审。
SDWebImage 流程
![SDWebImage流程圖.png](http://upload-images.jianshu.io/upload_images/1377007-c7e278abad7ecfed.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
以上是SDWebImage實現(xiàn)流程棘街,具體我們從以上實例來解析:
1.入口setImageWithURL:placeholderImage:options:
![UIImageView設置圖片.png](http://upload-images.jianshu.io/upload_images/1377007-d02678b87a71b600.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
會先把 placeholderImage 顯示,然后 SDWebImageManager 根據(jù) URL 開始處理圖片承边。這里值得注意的是蹬碧,開始加載之前圖片先取消對應的UIImageView先前的圖片下載操作。試想炒刁,如果我們給UIImageView設置了一張新的圖片恩沽,那么我們還會在意該UIImageVIew先前是要加載哪一張圖片么?應該是不在意的吧翔始!那是不是應該嘗試把該UIImageView先前的加載圖片相關操作給取消掉呢罗心。
```
[self sd_cancelCurrentImageLoad];
```
2.執(zhí)行到SDWebImageManagerdownloadWithURL:delegate:options:userInfo:,會先根據(jù)給定的URL生成一個唯一的Key,之后利用這個key到緩存中查找對應的圖片緩存城瞎。若內存緩存中沒有渤闷,則讀取磁盤緩存,如果存在磁盤緩存脖镀,那么將磁盤緩存讀到內存中成為內存緩存飒箭。如果都磁盤緩存也沒有的話,那么就在執(zhí)行的doneBlock中開始下載圖片蜒灰。
![讀取緩存圖片.png](http://upload-images.jianshu.io/upload_images/1377007-d4610de3361977e3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![下載圖片操作.png](http://upload-images.jianshu.io/upload_images/1377007-2fba7eec2d43a525.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
3.圖片下載由 NSURLConnection 來做弦蹂,實現(xiàn)相關 delegate 來判斷圖片下載中、下載完成和下載失敗强窖。
![設置NSURLConnection對象.png](http://upload-images.jianshu.io/upload_images/1377007-7fb8d287228d59c0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)![NSURLConnection對象實現(xiàn)代理.png](http://upload-images.jianshu.io/upload_images/1377007-023395e911b024af.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
4.connectionDidFinishLoading: 數(shù)據(jù)下載完成后交給 SDWebImageDecoder 做圖片解碼處理凸椿。
5.圖片解碼處理在一個 NSOperationQueue 完成,
不會拖慢主線程 UI翅溺。
6.在主線程 notifyDelegateOnMainThreadWithInfo:
宣告解碼完成脑漫,
imageDecoder:didFinishDecodingImage:userInfo:
回調給 SDWebImageDownloader髓抑。就不一一截圖了。
7.imageDownloader:didFinishWithImage:
回調給 SDWebImageManager 告知圖片下載完成优幸。
8.通知所有的 downloadDelegates 下載完成吨拍,
回調給需要的地方展示圖片。
9.將圖片保存到 SDImageCache 中网杆,
內存緩存和硬盤緩存同時保存撼玄。
寫文件到硬盤也在以單獨 NSInvocationOperation 完成陨闹,
避免拖慢主線程奴饮。
10.SDImageCache 在初始化的時候會注冊一些消息通知歇拆,
在內存警告或退到后臺的時候清理內存圖片緩存新啼,
應用結束的時候清理過期圖片追城。
11.SDWI 也提供了 UIButton+WebCache 和
MKAnnotationView+WebCache,方便使用燥撞。
22.SDWebImagePrefetcher 可以預先下載圖片座柱,
方便后續(xù)使用。
總結
SDWebImage作為一個優(yōu)秀的圖片加載框架物舒,提供的使用方法和接口對開發(fā)者來說非常友好色洞。其內部實現(xiàn)多是采用Block的方式來實現(xiàn)回調,代碼閱讀起來可能沒有那么直觀冠胯。本人能力有限火诸,文章中難免有錯誤以及認識不到位的地方,若大家在閱讀過程中有發(fā)現(xiàn)不合理或者錯誤的地方懇請在評論中指出荠察,我會在第一時間進行修正,不勝感激置蜀。
。