SDWebImage缓存策略
SDImageCache
在SDImageCache,图片采用了二级缓存策略。图片缓存时,在内存有缓存,在磁盘中也有缓存。其中,内存缓存是通过NSCache实现的。
缓存步骤
将图片缓存在内存中
判断图片的格式是png或是jpeg,将图片转化为
NSData数据如果是在mac_os系统中,直接将图片转化为
NSBitmapImageRep数据获取图片的存储路径,其中图片的文件名是通过传入的key经过md5加密后获得的。
将图片存储磁盘中
- (void)storeImage:(nullable UIImage *)image
imageData:(nullable NSData *)imageData
forKey:(nullable NSString *)key
toDisk:(BOOL)toDisk
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
if (!image || !key) {
if (completionBlock) {
completionBlock();
}
return;
}
// if memory cache is enabled
if (self.config.shouldCacheImagesInMemory) {
NSUInteger cost = SDCacheCostForImage(image);
[self.memCache setObject:image forKey:key cost:cost];
}
if (toDisk) {
dispatch_async(self.ioQueue, ^{
NSData *data = imageData;
if (!data && image) {
SDImageFormat imageFormatFromData = [NSData sd_imageFormatForImageData:data];
data = [image sd_imageDataAsFormat:imageFormatFromData];
}
[self storeImageDataToDisk:data forKey:key];
if (completionBlock) {
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock();
});
}
});
} else {
if (completionBlock) {
completionBlock();
}
}
}获取图片步骤
先在内存缓存中寻找
如果内存中找不到图片,则在默认的磁盘根目录中寻找,如果还是找不到,再从自定义的只读目录路径中寻找
获取图片数据后,将图片数据从
NSData转化为UIImage,转化是要根据图片的类型进行转化。默认对图片进行解压缩,生成位图图片。
将位图图片返回。
图片解压缩步骤
判断图片是否是动态图片,如果是,则不能解压缩
判断图片是否是透明的,如果是,则不能解压缩
判断图片的颜色空间模型是不是RGB,如果不是,不能解压缩
根据图片的大小创建一个上下文
将图片绘制在上下文中。
从上下文中读取一个不透明的位图图像,该图像就是解压缩后的图像
将位图图像返回
对图片进行缩放步骤
如果是普通图像,则直接进行缩放
如果是动态图像,则要对图像中的每一张图像都进行缩放
磁盘缓存清理步骤
获取磁盘中图片的最后修改日期。(为了减少磁盘和内存数据交换,读取是并不将整个文件读入内存,仅仅将文件的一些属性读入内存中,包括最后修改日期,该文件是否为文件夹,文件的大小和对应文件的文件路径)
根据最后修改日期将图片进行分类,将那些已经存放超过最长存放时间的文件存储在删除数组,其他的文件信息存储在另一个字典中。并计算除去要删除的文件之外的所有文件大小
根据删除数组中的文件路径,将对应的文件删除。
判断剩下的文件大小是否超过用户现在的磁盘最大容量。
如果超过,则将剩余的文件进行安修改时间进行升序排列,然后删除修改时间最早的文件,直到甚剩余文件大小小于最大磁盘容量的一半。
图片缓存清理时机
当系统发出内存不足通知时,会将内存中的所有图片缓存都删除掉。
当程序进入后台时,会对磁盘的文件数据进行清理。
当收到程序关闭通知时,会对磁盘中的文件数据进行清理。
如何判断imageData的图片类型。
根据imageData的第一个字节,可以判断其图片类型。
第一个字节
图片类型
0xFF
jpeg
0x89
png
0x47
gif
0x4D\0x49
tiff
0x52
将imageData的前12个字节转化为字符串,如果是RIFF前缀和WEBP后缀,则图片类型是webp``
Last updated