SDWebImage缓存策略

SDImageCache

SDImageCache,图片采用了二级缓存策略。图片缓存时,在内存有缓存,在磁盘中也有缓存。其中,内存缓存是通过NSCache实现的。

缓存步骤

  1. 将图片缓存在内存中

  2. 判断图片的格式是png或是jpeg,将图片转化为NSData数据

  3. 如果是在mac_os系统中,直接将图片转化为NSBitmapImageRep数据

  4. 获取图片的存储路径,其中图片的文件名是通过传入的key经过md5加密后获得的。

  5. 将图片存储磁盘中

- (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();
        }
    }
}

获取图片步骤

  1. 先在内存缓存中寻找

  2. 如果内存中找不到图片,则在默认的磁盘根目录中寻找,如果还是找不到,再从自定义的只读目录路径中寻找

  3. 获取图片数据后,将图片数据从NSData转化为UIImage,转化是要根据图片的类型进行转化。

  4. 默认对图片进行解压缩,生成位图图片。

  5. 将位图图片返回。

图片解压缩步骤

  1. 判断图片是否是动态图片,如果是,则不能解压缩

  2. 判断图片是否是透明的,如果是,则不能解压缩

  3. 判断图片的颜色空间模型是不是RGB,如果不是,不能解压缩

  4. 根据图片的大小创建一个上下文

  5. 将图片绘制在上下文中。

  6. 从上下文中读取一个不透明的位图图像,该图像就是解压缩后的图像

  7. 将位图图像返回

对图片进行缩放步骤

  1. 如果是普通图像,则直接进行缩放

  2. 如果是动态图像,则要对图像中的每一张图像都进行缩放

磁盘缓存清理步骤

  1. 获取磁盘中图片的最后修改日期。(为了减少磁盘和内存数据交换,读取是并不将整个文件读入内存,仅仅将文件的一些属性读入内存中,包括最后修改日期,该文件是否为文件夹,文件的大小和对应文件的文件路径)

  2. 根据最后修改日期将图片进行分类,将那些已经存放超过最长存放时间的文件存储在删除数组,其他的文件信息存储在另一个字典中。并计算除去要删除的文件之外的所有文件大小

  3. 根据删除数组中的文件路径,将对应的文件删除。

  4. 判断剩下的文件大小是否超过用户现在的磁盘最大容量。

  5. 如果超过,则将剩余的文件进行安修改时间进行升序排列,然后删除修改时间最早的文件,直到甚剩余文件大小小于最大磁盘容量的一半。

图片缓存清理时机

  1. 当系统发出内存不足通知时,会将内存中的所有图片缓存都删除掉。

  2. 当程序进入后台时,会对磁盘的文件数据进行清理。

  3. 当收到程序关闭通知时,会对磁盘中的文件数据进行清理。

如何判断imageData的图片类型。

根据imageData的第一个字节,可以判断其图片类型。

第一个字节

图片类型

0xFF

jpeg

0x89

png

0x47

gif

0x4D\0x49

tiff

0x52

将imageData的前12个字节转化为字符串,如果是RIFF前缀和WEBP后缀,则图片类型是webp``

Last updated