SDWebImageCache 源码

SDwebImageCache源码

主要类:
SDImageCache 缓存, 内存缓存、和磁盘缓存
SDMemoryCache 内存缓存, 里面设置了二级缓存
SDImageCacheConfig 缓存配置 , 缓存策略


SDMemoryCache : NSCache
weakCache 弱缓存,里面key是strong , value是weak 使用了NSHashMap 来进行内存的二级缓存
为什么使用NSCache?
这里原本使用key不用copying,但是有问题,特性没有使用
cost 这里可以存储多少个数据,超过的就去掉


SDImageCache 缓存:内存缓存、磁盘缓存

// 内存缓存> 磁盘缓存(缓存前编码图片)
- (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 = image.sd_memoryCost;
        [self.memCache setObject:image forKey:key cost:cost]; // NSCache
    }
    
    if (toDisk) {
        dispatch_async(self.ioQueue, ^{
            @autoreleasepool {
                NSData *data = imageData;
                if (!data && image) {
                    // If we do not have any data to detect image format, check whether it contains alpha channel to use PNG or JPEG format
                    SDImageFormat format;
                    if (SDCGImageRefContainsAlpha(image.CGImage)) {
                        format = SDImageFormatPNG;
                    } else {
                        format = SDImageFormatJPEG;
                    }
                    // 编码成为data对应的数据
                    data = [[SDWebImageCodersManager sharedInstance] encodedDataWithImage:image format:format];
                }
                // 存储在磁盘中
                [self _storeImageDataToDisk:data forKey:key];
            }
            
            if (completionBlock) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    completionBlock();
                });
            }
        });
    } else {
        if (completionBlock) {
            completionBlock();
        }
    }
}
// 获取图片

// 通过key获取缓存的图片
- (nullable UIImage *)imageFromCacheForKey:(nullable NSString *)key {
    // First check the in-memory cache...
    UIImage *image = [self imageFromMemoryCacheForKey:key];
    if (image) {
        return image;
    }
    
    // Second check the disk cache...
    image = [self imageFromDiskCacheForKey:key];
    return image;
}

// 通过key来获取磁盘中缓存的图片
- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key {
    UIImage *diskImage = [self diskImageForKey:key]; // 获取的过程,需要解码的配置就已经解码了
    if (diskImage && self.config.shouldCacheImagesInMemory) {
// 内存中没有,将磁盘的数据设置到内存的缓存中
        NSUInteger cost = diskImage.sd_memoryCost;
        [self.memCache setObject:diskImage forKey:key cost:cost];
    }

    return diskImage;
}

// 通过key获取对应的path
//defaultPath> customPath 的内容,缓存网上的> 包中预先设置的
// 获取的图片,对图片进行解码
// 也就是说:从缓存里面获取的图片将会先解码,存储的时候将会编码
- (nullable NSData *)diskImageDataBySearchingAllPathsForKey:(nullable NSString *)key {
    NSString *defaultPath = [self defaultCachePathForKey:key]; //获取缓存路径
    
//     后缀名字有无的处理
    NSData *data = [NSData dataWithContentsOfFile:defaultPath options:self.config.diskCacheReadingOptions error:nil];
    if (data) {
        return data;
    }

    // fallback because of https://github.com/SDWebImage/SDWebImage/pull/976 that added the extension to the disk file name
    // checking the key with and without the extension
    data = [NSData dataWithContentsOfFile:defaultPath.stringByDeletingPathExtension options:self.config.diskCacheReadingOptions error:nil];
    if (data) {
        return data;
    }

    // 我们自己自定义的内容
    NSArray *customPaths = [self.customPaths copy];
    for (NSString *path in customPaths) {
        NSString *filePath = [self cachePathForKey:key inPath:path];
        NSData *imageData = [NSData dataWithContentsOfFile:filePath options:self.config.diskCacheReadingOptions error:nil];
        if (imageData) {
            return imageData;
        }

        // fallback because of https://github.com/SDWebImage/SDWebImage/pull/976 that added the extension to the disk file name
        // checking the key with and without the extension
        // 可能给的路劲给的filePath 里面包含了后缀名字,对应的是没有后缀的名字
        imageData = [NSData dataWithContentsOfFile:filePath.stringByDeletingPathExtension options:self.config.diskCacheReadingOptions error:nil];
        if (imageData) {
            return imageData; // 图像数据
        }
    }

    return nil;
}

移除的代码 以及获取图片的大小 ,缓存的数据

PS: 小结

  1. 存储、移除 、获取图片数据的大小、默认预先设置的图片、以及缓存的配置
  2. 内存(NSCache > weakCache) > disk(defaultPath > customPaths)

你可能感兴趣的:(SDWebImageCache 源码)