SDWebImage源代码阅读(四)
border="0" width="530" height="100" src="http://music.163.com/outchain/player?type=2&id=29947420&auto=1&height=66">SDWebImage源代码阅读(一)——SDWebImage的使用和UIImageView+WebCache
SDWebImage源代码阅读(二)——SDWebImageManager
SDWebImage源代码阅读(三)——SDCache
SDWebImageDownloader
+ (SDWebImageDownloader *)sharedDownloader {
static dispatch_once_t once;
static id instance;
dispatch_once(&once, ^{
instance = [self new];
});
return instance;
}
单例
初始化
- (id)init {
if ((self = [super init])) {
_operationClass = [SDWebImageDownloaderOperation class];
_shouldDecompressImages = YES;
_executionOrder = SDWebImageDownloaderFIFOExecutionOrder;
_downloadQueue = [NSOperationQueue new];
_downloadQueue.maxConcurrentOperationCount = 6;
_downloadQueue.name = @"com.hackemist.SDWebImageDownloader";
_URLCallbacks = [NSMutableDictionary new];
#ifdef SD_WEBP
_HTTPHeaders = [@{@"Accept": @"image/webp,image/*;q=0.8"} mutableCopy];
#else
_HTTPHeaders = [@{@"Accept": @"image/*;q=0.8"} mutableCopy];
#endif
_barrierQueue = dispatch_queue_create("com.hackemist.SDWebImageDownloaderBarrierQueue", DISPATCH_QUEUE_CONCURRENT);
_downloadTimeout = 15.0;
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfig.timeoutIntervalForRequest = _downloadTimeout;
/**
* Create the session for this task
* We send nil as delegate queue so that the session creates a serial operation queue for performing all delegate
* method calls and completion handler calls.
*/
self.session = [NSURLSession sessionWithConfiguration:sessionConfig
delegate:self
delegateQueue:nil];
}
return self;
}
maxConcurrentOperationCount
对你最多并发数,默认为6
_downloadTimeout = 15.0
下载超时的时间
下载图片
- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url options:(SDWebImageDownloaderOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageDownloaderCompletedBlock)completedBlock {
···
}
其中执行
[self addProgressCallback:progressBlock completedBlock:completedBlock forURL:url createCallback:^{···}
使用dispatch_barrier_sync
保证只有一个队列执行,并且给URL添加回调函数,并且处理同一个网址下载的同一图片,保证每个URL都执行一次createCallback();
在createCallback()
我们会新创建一个操作队列,来执行下载操作
[wself.downloadQueue addOperation:operation];
就是将操作放入下载队列中
typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) {
/**
* Default value. All download operations will execute in queue style (first-in-first-out).
*/
SDWebImageDownloaderFIFOExecutionOrder,
/**
* All download operations will execute in stack style (last-in-first-out).
*/
SDWebImageDownloaderLIFOExecutionOrder
};
SDWebImageDownloader还提供了两种下载任务调度方式(先进先出和后进先出)
SDWebImageDownloaderOperation
初始化方法,在SDWebImageDownloader中调用:
- (id)initWithRequest:(NSURLRequest *)request
inSession:(NSURLSession *)session
options:(SDWebImageDownloaderOptions)options
progress:(SDWebImageDownloaderProgressBlock)progressBlock
completed:(SDWebImageDownloaderCompletedBlock)completedBlock
cancelled:(SDWebImageNoParamsBlock)cancelBlock {
if ((self = [super init])) {
_request = [request copy];
_shouldDecompressImages = YES;
_options = options;
_progressBlock = [progressBlock copy];
_completedBlock = [completedBlock copy];
_cancelBlock = [cancelBlock copy];
_executing = NO;
_finished = NO;
_expectedSize = 0;
_unownedSession = session;
responseFromCached = YES; // Initially wrong until `- URLSession:dataTask:willCacheResponse:completionHandler: is called or not called
}
return self;
}
SDWebImageDownloaderOperation使用start
和done
来控制状态,而不是使用main。图片的下载使用NSURLConnection
,在协议中接收数据并回调Block通知下载进度和下载完成。