今天總計一下SDWebImage核心模塊之下載模塊厌杜。下載模塊主要包括兩個類SDWebImageDownloader和SDWebImageDownloaderOperation贺嫂。其中SDWebImageDownloader負(fù)責(zé)對所有下載任務(wù)的管理竭鞍,SDWebImageDownloaderOperation負(fù)責(zé)具體的一個下載任務(wù)的執(zhí)行怔球。另外為了拓展下載功能,還支持實現(xiàn)SDWebImageDownloaderOperationInterface協(xié)議來自定義SDWebImageDownloaderOperation,根據(jù)需求自定義下載行為荐类。
SDWebImageDownloader內(nèi)部構(gòu)成
SDWebImageDownloader內(nèi)部持有一個下載隊列downloadQueue用于管理所有下載操作肃叶,一個緩存字典緩存所有的SDWebImageDownloaderOperation下載操作蹂随,一個httpheader的設(shè)置字典設(shè)置下載的請求頭信息,兩個信號鎖保證緩存字典和header頭字典的安全操作因惭。同時持有一個下載的session和下載session的對應(yīng)的配置文件NSURLSessionConfiguration岳锁。
SDWebImageDownloader主要方法
- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url
options:(SDWebImageDownloaderOptions)options
progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock {
__weak SDWebImageDownloader *wself = self;
return [self addProgressCallback:progressBlock completedBlock:completedBlock forURL:url createCallback:^SDWebImageDownloaderOperation *{
__strong __typeof (wself) sself = wself;
NSTimeInterval timeoutInterval = sself.downloadTimeout;
if (timeoutInterval == 0.0) {
timeoutInterval = 15.0;
}
// In order to prevent from potential duplicate caching (NSURLCache + SDImageCache) we disable the cache for image requests if told otherwise
//NSURLRequest生成
NSURLRequestCachePolicy cachePolicy = options & SDWebImageDownloaderUseNSURLCache ? NSURLRequestUseProtocolCachePolicy : NSURLRequestReloadIgnoringLocalCacheData;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url
cachePolicy:cachePolicy
timeoutInterval:timeoutInterval];
//設(shè)置cookie信息
request.HTTPShouldHandleCookies = (options & SDWebImageDownloaderHandleCookies);
request.HTTPShouldUsePipelining = YES;
//設(shè)置header信息
if (sself.headersFilter) {
request.allHTTPHeaderFields = sself.headersFilter(url, [sself allHTTPHeaderFields]);
}
else {
request.allHTTPHeaderFields = [sself allHTTPHeaderFields];
}
//組建SDWebImageDownloaderOperation
SDWebImageDownloaderOperation *operation = [[sself.operationClass alloc] initWithRequest:request inSession:sself.session options:options];
operation.shouldDecompressImages = sself.shouldDecompressImages;
//設(shè)置加密信息
if (sself.urlCredential) {
operation.credential = sself.urlCredential;
} else if (sself.username && sself.password) {
operation.credential = [NSURLCredential credentialWithUser:sself.username password:sself.password persistence:NSURLCredentialPersistenceForSession];
}
//設(shè)置優(yōu)先級
if (options & SDWebImageDownloaderHighPriority) {
operation.queuePriority = NSOperationQueuePriorityHigh;
} else if (options & SDWebImageDownloaderLowPriority) {
operation.queuePriority = NSOperationQueuePriorityLow;
}
//設(shè)置隊列
if (sself.executionOrder == SDWebImageDownloaderLIFOExecutionOrder) {
// Emulate LIFO execution order by systematically adding new operations as last operation's dependency
[sself.lastAddedOperation addDependency:operation];
sself.lastAddedOperation = operation;
}
return operation;
}];
}
此方法用于對外的暴露,實際上進(jìn)行了SDWebImageDownloaderOperation的生成的相關(guān)設(shè)置工作蹦魔。NSURLRequest生成并設(shè)置的header信息激率、cookie信息設(shè)置。NSURLRequest版姑、session柱搜、配置options生成DownloaderOperation. DownloaderOperation設(shè)置加密、優(yōu)先級剥险、隊列聪蘸。最后通過addProgressCallback方法將operation緩存,并添加到操作隊列中addOperation。
SDWebImageDownloader下載選項
SDWebImageDownloader提供了很多下載選項健爬,可以根據(jù)情況進(jìn)行配置控乾。如設(shè)置下載優(yōu)先級、進(jìn)度娜遵、后臺下載蜕衡,圖片縮放等,同時支持先進(jìn)先出设拟,先進(jìn)后出的下載方式慨仿。
typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) {
//下載低優(yōu)先級
SDWebImageDownloaderLowPriority = 1 << 0,
//下載高優(yōu)先級
SDWebImageDownloaderHighPriority = 1 << 7,
// 帶有進(jìn)度
SDWebImageDownloaderProgressiveDownload = 1 << 1,
//默認(rèn)不使用URLCache
SDWebImageDownloaderUseNSURLCache = 1 << 2,
//如果圖片是在NSURLCAche中讀取時,調(diào)用completion block時纳胧,返回nil镰吆,配合SDWebImageDownloaderUseNSURLCache使用
SDWebImageDownloaderIgnoreCachedResponse = 1 << 3,
//支持后臺下載
SDWebImageDownloaderContinueInBackground = 1 << 4,
//支持NSHTTPCookieStore的cookie信息,進(jìn)而設(shè)置NSMutableURLRequest.HTTPShouldHandleCookies=YES
SDWebImageDownloaderHandleCookies = 1 << 5,
//允許不信任SSL證書
SDWebImageDownloaderAllowInvalidSSLCertificates = 1 << 6,
//縮放大圖片
SDWebImageDownloaderScaleDownLargeImages = 1 << 8,
};
typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) {
//先進(jìn)先出
SDWebImageDownloaderFIFOExecutionOrder,
//先進(jìn)后出
SDWebImageDownloaderLIFOExecutionOrder
};
SDWebImageDownloader默認(rèn)配置
1.解壓縮shouldDecompressImages:默認(rèn)情況下跑慕,圖片下載下來就解壓縮万皿,這是拿空間換時間的做法,讓圖片在使用時能更快的加載核行。
2.最大下載數(shù)maxConcurrentDownloads:此屬性實質(zhì)是設(shè)置下載隊列(NSOperationQueue)的最大數(shù)并發(fā)數(shù)牢硅。
3.當(dāng)前最大下載數(shù)currentDownloadCount:當(dāng)前下載隊列中未執(zhí)行完畢的操作個數(shù)
4.下載超時時間downloadTimeout:默認(rèn)設(shè)置為15秒
5.下載隊列executionOrder:默認(rèn)是先進(jìn)先出,先到先下載的隊列
SDWebImageDownloaderOperation
SDWebImageDownloaderOperation持有NSURLSessionTask和NSURLRequest芝雪,在start方法中創(chuàng)建網(wǎng)絡(luò)請求并執(zhí)行减余,在URLSession:task:didCompleteWithError:中進(jìn)行數(shù)據(jù)的整合處理,反饋給外部惩系。
總結(jié):
SDWebImage的下載管理模塊SDWebImageDownloader采用了NSOperationQueue來管理隊列佳励,而沒有使用更加高效的GCD來完成。這是因為下載的業(yè)務(wù)的復(fù)雜性比較高蛆挫,如優(yōu)先級設(shè)置、取消操作妙黍、操作狀態(tài)的監(jiān)控悴侵、操作的依賴性,這些如果用GCD來封裝的話拭嫁,最后的結(jié)果就是寫出一個NSOperationQueue出來可免,所以我猜作者肯定想何必再封裝造輪子呢,直接使用NSOperationQueue得了做粤。