3. downloadImageWithURL下载方法的具体实现
方法在SDWebImageManager.m中
1 | id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url |
参数:
- url
- options
- 之前已经介绍了 SDWebImageOptions
progressBlock
- SDWebImageDownloaderProgressBlock 定义在 SDWebImageDownloader.h 中具体实现为:
1
2
3//从名字可以看出来第一个参数是已经接受了数据的大小
//另一个参数表示总数据的大小
typedef void(^SDWebImageDownloaderProgressBlock)(NSInteger receivedSize, NSInteger expectedSize);
- SDWebImageDownloaderProgressBlock 定义在 SDWebImageDownloader.h 中具体实现为:
completedBlock
- 图片下载完要做的块 具体实现为:
1
2
typedef void(^SDWebImageCompletionWithFinishedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL);
- 图片下载完要做的块 具体实现为:
然后一看这个方法实现……麻蛋 好长!
3.1 一些判断
这个没什么好说的
1 |
|
3.2 SDWebImageCombinedOperation
下来看到了一个类 SDWebImageCombinedOperation
1 |
|
它的具体实现:
1 |
|
它实现了 SDWebImageOperation好歹是回答了之前的问题3
- 回答问题3(部分):SDWebImageOperation的实现之一是SDWebImageCombinedOperation
但是这个cacheOperation 命名令我很困惑。。因为到现在还不知道下载操作会放在那里。。
- 问题7 : SDWebImageCombinedOperation的cacheOperation执行什么操作
然后它的属性cancelBlock是 长这样的 typedef void(^SDWebImageNoParamsBlock)();
好像没什么用的样子。。
3.3 isFailedUrl
1 |
|
这里 终于解决了之前的第四个问题,failedURLs就储存了失效的url,也就是依据这个做出不重复下载的功能
- 回答问题4: 不重复下载相同url 是根据SDWebImageManager.failedURLs来实现的
看到这里 还没有看见下载的功能。。判断了这么多条件 真是值得学习啊。。
3.4 储存operation,生成cacheOperation实例
1 |
|
之前不是猜测 SDWebImageCombinedOperation中的 cacheOperation是缓存还是下载的操作吗,到这里就可以猜出来,应该是缓存和下载操作都有,因为要是只是缓存操作的话,这个操作不会进行很久,一般也不需要储存起来管理。
1 |
|
来看看它的实现:
1 |
|
其中 cacheKeyFilter是过滤url用的,它是个SDWebImageCacheKeyFilterBlock块,作者注解中写的很清楚了,它可以用来删除url中动态生成的部分,比如一些“?”之后的参数什么的,但是我没用到,这里就不讨论如何自定义这个SDWebImageCacheKeyFilterBlock块了。
接下来看吧:
1 |
|
这里终于要开始实现cacheoperation了。。
其中self.imageCache 是在init方法中生成的 就是生成一个SDImageCache的单例:1
2
3
4
- (SDImageCache *)createCache {
return [SDImageCache sharedImageCache];
}
接着来看queryDiskCacheForKey:
1 |
|
我这流程中 图片是第一次下载的,所以就按着 内存和本地中都找不到流程走。
看到这里,有点奇怪为什么这里要加autorealeasepool,看了下资料,说是可以优化内存。
3.5 关于SDWebImageManager的单例(流程之外)
一开始看见它的单例是这么写,这不一看就知道不是严格的单例吗
1 |
|
一开始我还以为是用了什么高级的Runtime使创建出来的对象严格保持单例,结果实验了一下:
1 |
|
打印出来:
sdwebImageTest[4350:1125408] m1 :<SDWebImageManager: 0x17550510>
sdwebImageTest[4350:1125408] m2 :<SDWebImageManager: 0x175537e0>
摔!这不就是《只要你确保只调用sharedManager就确保单例》的做法吗。。作者开心就好。。反正里面的单例模式大家都只调用默认的sharedManager方法就不会错。。