1. 程式人生 > >iOS圖片加載框架-SDWebImage解讀

iOS圖片加載框架-SDWebImage解讀

git -i 都沒有 一定的 get gets src some 進行

在iOS的圖片加載框架中,SDWebImage可謂是占據大半壁江山。它支持從網絡中下載且緩存圖片,並設置圖片到對應的UIImageView控件或者UIButton控件。在項目中使用SDWebImage來管理圖片加載相關操作可以極大地提高開發效率,讓我們更加專註於業務邏輯實現。

SDWebImage 概論

1.提供了一個UIImageView的category用來加載網絡圖片並且對網絡圖片的緩存進行管理
2.采用異步方式來下載網絡圖片
3.采用異步方式,使用memory+disk來緩存網絡圖片,自動管理緩存。
4.支持GIF動畫
5.支持WebP格式
6.同一個URL的網絡圖片不會被重復下載
7.失效的URL不會被無限重試
8.耗時操作都在子線程,確保不會阻塞主線程
9.使用GCD和ARC
10.支持Arm64

SDWebImage 使用

1.使用IImageView+WebCache category來加載UITableView中cell的圖片

[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

2.使用Blocks,采用這個方案可以在網絡圖片加載過程中得知圖片的下載進度和圖片加載成功與否

[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的實現提供接口。

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方式,但那個並不是我們經常用到的。基本上面所講的3個方法都能滿足需求。

SDWebImage 流程

技術分享
UIImageView的圖片加載流程

SDWebImage 接口

SDWebImage是一個成熟而且比較龐大的框架,但是在使用過程中並不需要太多的接口,這算是一種代碼封裝程度的體現。這裏就介紹比較常用的幾個接口。

  1. 給UIImageView設置圖片的接口,SDWebImage有提供多個給UIImageView設置圖片的接口,最終所有的接口都會調用下圖的這個接口,這是大多數框架的做法。

    技術分享
    給UIImageView設置圖片的接口
  2. 獲取SDWebImage的磁盤緩存大小,在項目中有時候會需要統計應用的磁盤緩存內容大小,那麽獲取圖片的緩存大小就是使用這個接口來實現

    [SDImageCache sharedImageCache] getSize];
  3. 清理內存緩存,清理內存中緩存的圖片資源,釋放內存資源。

    [[SDImageCache sharedImageCache] clearMemory];
  4. 有了清理內存緩存,自然也有清理磁盤緩存的接口

    [[SDImageCache sharedImageCache] clearDisk];

SDWebImage 解析

解析主要圍繞著SDWebImage的圖片加載流程來分析,介紹SDWebImage這個框架加載圖片過程中的一些處理方法和設計思路。

  1. 給UIImageView設置圖片,然後SDWebImage調用這個最終的圖片加載方法。

    技術分享
    1 給UIImageView設置圖片
  2. 開始加載之前圖片先取消對應的UIImageView先前的圖片下載操作。試想,如果我們給UIImageView設置了一張新的圖片,那麽我們還會在意該UIImageVIew先前是要加載哪一張圖片麽?應該是不在意的吧!那是不是應該嘗試把該UIImageView先前的加載圖片相關操作給取消掉呢。

     [self sd_cancelCurrentImageLoad]

    技術分享
    2 取消對應的UIImageView先前的圖片下載操作

該方法經過周轉,最後調用了以下方法,框架將圖片對應的下載操作放到UIView的一個自定義字典屬性(operationDictionary)中,取消下載操作第一步也是從這個UIView的自定義字典屬性(operationDictionary)中取出所有的下載操作,然後依次調用取消方法,最後將取消的操作從(operationDictionary)字典屬性中移除。

技術分享
最終的取消下載方法

3.移除之前沒用的圖片下載操作之後就創建一個新的圖片下載操作,然後設置到UIView的一個自定義字典屬性(operationDictionary)中。

技術分享
3 創建一個新的圖片下載操作

4.看看如何創建一個新的圖片下載操作,框架保存了一個失效的URL列表,如果URL失效了就會被加入這個列表,保證不會重復多次請求失效的URL。

技術分享
4 圖片下載操作

根據給定的URL生成一個唯一的Key,之後利用這個key到緩存中查找對應的圖片緩存。

技術分享
查找圖片緩存

5.讀取圖片緩存,根據key先從內存中讀取圖片緩存,若沒有命中內存緩存則讀取磁盤緩存,如果磁盤緩存命中,那麽將磁盤緩存讀到內存中成為內存緩存。如果都沒有命中緩存的話,那麽就在執行的doneBlock中開始下載圖片。

技術分享
5 讀取圖片緩存

6.圖片下載操作完成後會將圖片對應的數據通過completed Block進行回調

技術分享
6 圖片下載操作

在圖片下載方法中,調用了一個方法用於添加創建和下載過程中的各類Block回調。

技術分享
圖片下載方法

添加該URL加載過程的狀態回調Block

技術分享
狀態回調Block

如果該URL是第一次加載的話,那麽就會執行createCallback這個回調Block,然後在createCallback裏面開始構建網絡請求,在下載過程中執行各類進度Block回調。

技術分享
構建網絡請求

7.當圖片下載完成之後會回到done的Block回調中做圖片轉換處理和緩存操作

技術分享
7 圖片轉換處理和緩存操作

回到UIImageView控件的設置圖片方法Block回調中,給對應的UIImageView設置圖片,操作流程到此完成。

技術分享
Block中設置圖片

總結

SDWebImage作為一個優秀的圖片加載框架,提供的使用方法和接口對開發者來說非常友好。其內部實現多是采用Block的方式來實現回調,代碼閱讀起來可能沒有那麽直觀。此文章旨在給大家講解SDWebImage這個框架的圖片大概加載流程,其中具體細節限於篇幅無法詳細深究。本人能力有限,文章中難免有錯誤,若大家在閱讀過程中有發現不合理或者錯誤的地方懇請在評論中指出,我會在第一時間進行修正,不勝感激

若是本文章對你起了一定的作用,請在下方中點個,讓我知道這文章起了它應該起的作用,也算是對我的辛苦碼字的鼓勵吧,哈哈!

==========================================
評論中有一位朋友想了解關於304的處理,我這裏補充說明下。

SDWebImage在加載圖片網絡請求的NSURLConnection的代理中對httpCode 做了判斷,當httpCode為304的時候放棄下載,讀取緩存。

技術分享
304處理


作者:要上班的斌哥
鏈接:http://www.jianshu.com/p/be9a0a088feb
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請註明出處。

iOS圖片加載框架-SDWebImage解讀