接上一篇文章继续分析SDWebImage5.11的
缓存
部分
SDImageCache
缓存获取数据,主要是通过
key
缓存(上一篇文章有说),cacheType
判断缓存方式,options
进行缓存拓展。主要内容如下:a. 对
cacheOptions
类型进行筛选b. 进入
queryCacheOperationForKey
方法,对具体缓存方式进行划分,其中包括内存缓存,磁盘缓存。然后又在各自缓存下面进行了详细划分,具体看源码
这里只挑几个重点代码
a、内存查找(为啥说缓存的查找是先内存呢,看下面这段代码)
// 先检查内存里面的缓存
UIImage *image;
if (queryCacheType != SDImageCacheTypeDisk) {
// 通过key去内存表拿到value(image),默认实现表为weak(NSMapTable<KeyType, ObjectType> *weakCache)
image = [self imageFromMemoryCacheForKey:key];
}
一般的queryCacheType
默认为SDImageCacheTypeAll
,在没有自定义queryCacheType
为SDImageCacheTypeDisk
的情况下都是先走的memoryCache
而imageFromMemoryCacheForKey
这个方法里面的查找方式也很简单,通过封装SDMemoryCache
协议,并用NSMapTable<KeyType, ObjectType>
类型存储的值去取到对应的image
// 是否只能在内存缓存查询,是的话直接将找到的image回调,注意这里是不查询data,所以data为nil
// 默认情况下,在内存缓存找到image是不查询data了,但是设置了SDImageCacheQueryMemoryData,就会强制去查询
BOOL shouldQueryMemoryonly = (queryCacheType == SDImageCacheTypeMemory) || (image && !(options & SDImageCacheQueryMemoryData));
if (shouldQueryMemoryOnly) {
if (doneBlock) {
doneBlock(image, nil, SDImageCacheTypeMemory);
}
return nil;
}
正常情况下,如果照片找到了,就直接回调block。但是在queryCacheType
不指定为SDImageCacheTypeMemory
,且options
为SDImageCacheQueryMemoryData
的时候那就得继续往下,去磁盘
查找。
b、磁盘查找
磁盘查找分为同步跟异步,默认情况是异步查找,以下情况是同步查找
BOOL shouldQueryDiskSync = ((image && options & SDImageCacheQueryMemoryDataSync) ||
(!image && options & SDImageCacheQueryDiskDataSync));
磁盘的查找有2种方式
一种是通过SDDiskCache
协议内部封装的方法,通过key获取path,然后拿到data
一种是通过additionalCachePathBlock
拿到保存的path,然后拿到data
如果是通过磁盘拿到的image,还会将image保存到内存,以便下次查询。
这里说个小细节,磁盘查询的过程是用了
@autoreleasepool
包了起来,为了防止多张照片查询,引起的内存飙升。