
SDWebImageDownloaderOperation
繼承于NSOperation的下載類操作,它是多線程的方案,實際也是基于GCD開發(fā),為抽象類。
1
@synchronized (self) 其作用是防止資源競爭和線程安全,防止不同的線程在同一時間去修改某段代碼塊,即所謂的互斥鎖。
2
當(dāng)Operation是isCancelled狀態(tài)時,重置數(shù)據(jù)等并置為Finish。
3
本類可能持有兩個下載會話URLSession。unownedSession可能是為WebImageDownloader傳過來的,在這里就weak修飾,如為空則創(chuàng)建一個strong修飾的ownedSession
@property (weak, nonatomic) NSURLSession *unownedSession;
@property (strong, nonatomic) NSURLSession *ownedSession;
4
-(void)cancel方法:判斷NSTHread是否在當(dāng)前線程,如果是則判斷Operation的狀態(tài)(finish則不處理,unfinish則繼續(xù)取消操作),否的話dataTask取消接收并發(fā)送暫停下載的通知。
5
在NSURLSessionDataDelegate代理中,會根據(jù)Web服務(wù)器端響應(yīng)HTTP的狀態(tài)碼來作相應(yīng)的數(shù)據(jù)處理。簡單來看看HTTP的狀態(tài)碼:
- 2XX (200、201、202...) 代表請求已成功被服務(wù)器接收理解等
- 3XX (301、302、303..) 重定向,客戶端需進(jìn)一步操作完成請求
- 4XX (400,403,404..) 客戶端發(fā)生錯誤
- 5XX (500、502、504..) 服務(wù)器錯誤,無法完成有效請求
6
在接收數(shù)據(jù)的回調(diào)處理過程
(void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data
獲取圖片的信息等,修正圖片Image的方向、分辨率等,然后進(jìn)行繪制,解碼等操作。
至此,可能圖片Image已經(jīng)下載完成并解碼成功,因此也在這里面把圖片以URL為key命名。
SDWebImageManager
SDWebImageManager是UIImageView+WebCache背后的異步下載管理類,它維護(hù)著一個下載類SDWebImageDownloader,一個圖片緩存管理類imageCache。同時它可以單獨抽出來使用(下載并加載網(wǎng)絡(luò)圖片),不僅限于在UIImageView的分類中使用。
1
/**
* The cache filter is a block used each time SDWebImageManager need to convert an URL into a cache key. This can
* be used to remove dynamic part of an image URL.
*
* The following example sets a filter in the application delegate that will remove any query-string from the
* URL before to use it as a cache key:
*
* @code
[[SDWebImageManager sharedManager] setCacheKeyFilter:^(NSURL *url) {
url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path];
return [url absoluteString];
}];
* @endcode
*/
@property (nonatomic, copy) SDWebImageCacheKeyFilterBlock cacheKeyFilter;
這個Block主要作用是滿足開發(fā)者對圖片URL存儲為緩存時的名字的過濾,用來移除URL的動態(tài)部分信息,如端口號什么的。
2
在- (void)cancelAll里學(xué)習(xí)下NSArray的makeObjectsPerformSelector方法。
分別為:
- (void)makeObjectsPerformSelector:(SEL)aSelector NS_SWIFT_UNAVAILABLE("Use enumerateObjectsUsingBlock: or a for loop instead");
- (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(nullable id)argument NS_SWIFT_UNAVAILABLE("Use enumerateObjectsUsingBlock: or a for loop instead");
類似于For循環(huán),即對NSArray(NSSet)包含的對象進(jìn)行并發(fā)的遍歷。既然是對Object遍歷,當(dāng)然就NSArray里就不能是常用基本類型了(需轉(zhuǎn)化成NSNumber等)。aSelector即Object的方法名。
3
- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url
options:(SDWebImageOptions)options
progress:(SDWebImageDownloaderProgressBlock)progressBlock
completed:(SDWebImageCompletionWithFinishedBlock)completedBlock;
SDWebImageManager的核心方法,作者首先嚴(yán)謹(jǐn)?shù)貙?shù)URL作了容錯處理。即參數(shù)URL可能為NSString類型的情況。
當(dāng)非SDWebImageRetryFailed且圖片已經(jīng)下載失敗的情形時,返回error的CompletedBlock。
接著,查詢該URL圖片是否已經(jīng)在Cache中或者Disk中。
- 如果緩存中沒有Image,沒有實現(xiàn)
- (BOOL)imageManager:(SDWebImageManager *)imageManager shouldDownloadImageForURL:(NSURL *)imageURL代理,繼而判斷SDWebImageDownloaderOptions類型,從而進(jìn)行對URL圖片的下載操作。 - 如果Image存在于緩存中,取出并返回,返回
SDWebImageCompletionWithFinishedBlock的操作都是在Main線程中,并移除在runningOperations中的下載任務(wù)。
這里面作了大量的下載選項的處理??赡芸雌饋肀容^多和煩,但理清了,看過了SDWebImageDownloader和SDImageCache,也很好理解的了。