1. 程式人生 > >讀SDWebImage原始碼第二天的收穫與思考(二)

讀SDWebImage原始碼第二天的收穫與思考(二)

4.如果找到了就直接顯示給當前檢視,如果沒有找到就就去通過操作佇列進行下載。

那麼接下來我們看一下是如何下載的?

思考? 如果不做下載和快取的話,那麼圖片數量過多,每次都要重新載入請求,那麼會消耗很多流量及其他資源。那麼如果下載?圖片是否進行了壓縮呢?我們先看下 SDWebImage作者最初的版本是怎麼做的?

if (cachedImage)

{

  self.image = cachedImage;

} else {

if (downloadQueue == nil) {

downloadQueue = [[NSOperationQueue alloc] init];

[downloadQueue setMaxConcurrentOperationCount:8];

}

currentOperation = [[DMWebImageDownloadOperation alloc] initWithURL:url delegate:self]; [downloadQueue addOperation:currentOperation]; }

第一步:先判斷 NSOperationQueue的 downloadQueue 下載佇列例項是否為空,如果為空 那麼就建立一個,然後設定 可同時執行的排隊操作的最大數目。(多執行緒可以有時間好好研究研究)。

第二步: DMWebImageDownloadOperation : NSOperation , currentOperation = [[DMWebImageDownloadOperation alloc] initWithURL:url delegate:self]; 先建立一個 NSOperation 操作任務物件,設定 url 和把當前的圖片檢視UIIMageView物件,傳過去。

@property (retain) NSURL *url; @property (assign) DMWebImageView *delegate;

  • (id)initWithURL:(NSURL *)anUrl delegate:(DMWebImageView *)aDelegate { if (self = [super init]) { self.url = anUrl; self.delegate = aDelegate; }

    return self; }

第三步: [downloadQueue addOperation:currentOperation];

把當前配置好的操作任務加到下載佇列裡。

然後思考? 程式碼如果按直接閱讀的話 那麼就結束了。疑惑啊!哪裡有下載呢?一看我們中間用了 NSOperation ,快來看看它的生命週期吧。在第二步的時候,它究竟幹了什麼?

關於 NSOperation 的 main 方法

第四步: 當我執行完第三步的時候,程式碼直接進到了 NSOperation 的 main 方法 裡

首先判斷 if (self.isCancelled) ,當前的操作任務是否取消了,如果取消了那麼就直接返回。 { return; }

否則:

這個時候可以用咱們當時最開始的時候,沒有用第三方自己顯示圖片的那一套方法了: 把URL轉化為data二進位制資料。然後給UIImage , 在mrc裡,如果物件使用完畢要及時進行釋放,對用完的物件data進行釋放。

//這一步寫到下一篇文章分析 第五步: if (!self.isCancelled) { [delegate performSelectorOnMainThread:@selector(downloadFinishedWithImage:) withObject:image waitUntilDone:YES]; }

知識點擴充: NSOperation物件需要定期地呼叫isCancelled方法檢測操作是否已經被取消,如果返回YES(表示已取消),則立即退出執行。不管是自定義NSOperation子類,還是使用系統提供的兩個具體子類,都需要支援取消。isCancelled方法本身非常輕量,可以頻繁地呼叫而不產生大的效能損失 以下地方可能需要呼叫isCancelled:

  • 在執行任何實際的工作之前
  • 在迴圈的每次迭代過程中,如果每個迭代相對較長可能需要呼叫多次
  • 程式碼中相對比較容易中止操作