在SDWebImage3.7.5源码阅读二中看完后,已经知道SDWebImageCombinedOperation
类的cacheOperation属性就是在图片下载前准备搜索一下缓存(memory、disk)作用的。
- 回答问题7:SDWebImageCombinedOperation的cacheOperation执行的操作是在下载前搜索图片缓存。
3.6 下载操作
在cacheOperation搜索完缓存之后:
operation.cacheOperation = [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType) {
...
operation.cacheOperation = [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType) {
...//一大串 options的操作 暂时不管它
//终于见到了下载操作!
id <SDWebImageOperation> subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed
...
}
其中self.imageDownloader
也是SDWebImageManager init的时候生成的,是SDWebImageDownloader
对象,跳转到downloadImageWithURL
中:
- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url options:(SDWebImageDownloaderOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageDownloaderCompletedBlock)completedBlock {
__block SDWebImageDownloaderOperation *operation;
__weak __typeof(self)wself = self;
[self addProgressCallback:progressBlock completedBlock:completedBlock forURL:url createCallback:^{
//生成对应的URL
NSMutableURLRequest *request = ...
//下载进度 下载完成 取消等操作
operation = [[wself.operationClass alloc] initWithRequest ...
}];
...
//开始下载
[wself.downloadQueue addOperation:operation];
}
然后查看SDWebImageDownloaderOperation
可以看到下载实现是靠 NSURLConnection
完成的,下载进度什么的当然就是NSURLConnectionDataDelegate
里完成的。
图片下载完后有个decode操作:
image = [UIImage decodedImageWithImage:image];
到这里整理一下主要的流程:
- 入口 setImageWithURL:placeholderImage:options: 会先把 placeholderImage 显示,然后 SDWebImageManager 根据 URL 开始处理图片。
- 进入 SDWebImageManager-downloadWithURL:delegate:options:userInfo:,交给 SDImageCache 从缓存查找图片是否已经下载 queryDiskCacheForKey:key done:.
- 先从内存图片缓存查找是否有图片,如果内存中已经有图片缓存 SDWebImageQueryCompletedBlock 块返回图片 到前端展示图片。
- 如果内存缓存中没有,GCD 异步开始从硬盘查找图片是否已经缓存。
- 根据 URLKey 在硬盘缓存目录下尝试读取图片文件。 完成后在SDWebImageQueryCompletedBlock回调
- 如果上一操作从硬盘读取到了图片,图片可能先缩放再转码,将图片添加到内存缓存中
- 如果从硬盘缓存目录读取不到图片,说明所有缓存都不存在该图片,需要下载图片,
共享或重新生成一个下载器 SDWebImageDownloader 开始下载图片。 - 图片下载由 NSURLConnection 来做,实现相关 delegate 来判断图片下载中、下载完成和下载失败。
- connection:didReceiveData: 中利用 SDWebImageQueryCompletedBlock 做了按图片下载进度加载效果。
- connectionDidFinishLoading: 数据下载完成后交给 SDWebImageDecoder 做图片解码处理。
- 下载完成后有缓存,交给 SDWebImageDecoder 做图片解码操作。