SDWebImage375源码-叁

SDWebImage3.7.5源码阅读二中看完后,已经知道SDWebImageCombinedOperation类的在cacheOperation搜索完缓存之后:

1
2
3
4
5
6
7
8
9
10
11
12
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中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (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操作:

1
image = [UIImage decodedImageWithImage:image];

到这里整理一下主要的流程:

  1. 入口 setImageWithURL:placeholderImage:options: 会先把 placeholderImage 显示,然后 SDWebImageManager 根据 URL 开始处理图片。
  2. 进入 SDWebImageManager-downloadWithURL:delegate:options:userInfo:,交给 SDImageCache 从缓存查找图片是否已经下载 queryDiskCacheForKey:key done:.
  3. 先从内存图片缓存查找是否有图片,如果内存中已经有图片缓存 SDWebImageQueryCompletedBlock 块返回图片 到前端展示图片。
  4. 如果内存缓存中没有,GCD 异步开始从硬盘查找图片是否已经缓存。
  5. 根据 URLKey 在硬盘缓存目录下尝试读取图片文件。 完成后在SDWebImageQueryCompletedBlock回调
  6. 如果上一操作从硬盘读取到了图片,图片可能先缩放再转码,将图片添加到内存缓存中
  7. 如果从硬盘缓存目录读取不到图片,说明所有缓存都不存在该图片,需要下载图片,
    共享或重新生成一个下载器 SDWebImageDownloader 开始下载图片。
  8. 图片下载由 NSURLConnection 来做,实现相关 delegate 来判断图片下载中、下载完成和下载失败。
    • connection:didReceiveData: 中利用 SDWebImageQueryCompletedBlock 做了按图片下载进度加载效果。
    • connectionDidFinishLoading: 数据下载完成后交给 SDWebImageDecoder 做图片解码处理。
  9. 下载完成后有缓存,交给 SDWebImageDecoder 做图片解码操作。