SDWebImage源码解析

SDWebImage在iOS开发中广泛用于网络图片加载,它提供了下载、解码、缓存等功能。本文深入解析其主调用函数、内存/磁盘缓存、下载过程、解压和存储操作,以及内存管理和清理机制。
摘要由CSDN通过智能技术生成

SDWebImage已经在iOS开发中被广泛使用,提供了UIImageView和UIButton的分类,解决了需要从网络上加载图片的烦恼。SDWebImage的强大之处不仅在于提供图片的下载,还提供了图片的解码,超大图片的按比例解码,图片的缓存及内存占用超额的清理等功能!

流程图

上面是SDWebImage主要对图片下载、处理、解压、存储等功能的主要类功能分布,接下来我们来依次解析每个步骤的功能!!

 

功能

我们接下来按照框架中的功能步骤来一步一步解析代码,我们会依次从主调用函数、查询内存或磁盘中的图片、下载图片、解压图片、存储图片、清理缓存等来展开讲解!!

  • 主调用函数(UIKit层)
- (void)sd_setImageWithURL:(nullable NSURL *)url;
- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder;
- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(SDWebImageOptions)options;
- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(SDWebImageOptions)options
                  progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
                 completed:(nullable SDExternalCompletionBlock)completedBlock;

/**  这些函数底层都是调用了 UIView+WebCache 类方法  **/
- (void)sd_internalSetImageWithURL:(nullable NSURL *)url
                  placeholderImage:(nullable UIImage *)placeholder
                           options:(SDWebImageOptions)options
                      operationKey:(nullable NSString *)operationKey
             internalSetImageBlock:(nullable SDInternalSetImageBlock)setImageBlock
                          progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
                         completed:(nullable SDExternalCompletionBlock)completedBlock
                           context:(nullable NSDictionary<NSString *, id> *)context;

sd_internalSetImageWithURL解析:

  1. 根据operationKey判断当前是否有相同的下载队列,有的话则取消;
  2. 若设置了placeholder占位图,则在主线程先显示占位图片;
  3. 判断是否需要显示菊花加载view,需要则加上;
  4. 查询加载图片,调用函数到内存或磁盘中是否有当前图片的存在;

 

  • 查询内存中的图片

1、NSCache

  • NSCache是一个类似NSDictionary一个可变的集合;
  • 提供了可设置缓存的数目与内存大小限制的方式;
  • 保证了处理的数据的线程安全性;
  • 缓存使用的key不需要是实现NSCopying的类;
  • 当内存警告时内部自动清理部分缓存数据;
@property (strong, nonatomic, nonnull) SDMemoryCache *memCache;

- (void)storeImage:(nullable UIImage *)image
         imageData:(nullable NSData *)imageData
            forKey:(nullable NSString *)key
            toDisk:(BOOL)toDisk
        completion:(nullable SDWebImageNoParamsBlock)completionBlock {

    // 将图片保存到Cache中
    if (self.config.shouldCacheImagesInMemory) {
        NSUInteger cost = image.sd_memoryCost;
        [self.memCache setObject:image forKey:key cost:cost];
    }
}

// setter方法设置大小,个数限制等
- (void)setMaxMemoryCost:(NSUInteger)maxMemoryCost {
    self.memCache.totalCostLimit = maxMemoryCost;
}

- (NSUInteger)maxMemoryCost {
    return self.memCache.totalCostLimit;
}

- (NSUInteger)maxMemoryCountLimit {
    return self.memCache.countLimit;
}

- (void)setMaxMemoryCountLimit:(NSUInteger)maxCountLimit {
    self.memCache.countLimit = maxCountLimit;
}

2、weakCache(NSMapTable)

  • 由于NSCache内存自动清理机制有可能会出现存储资源太多导致某些资源被内存释放;
  • weakCache是NSMapTable类型,用法与类似NSDictionary,而且可以设置key与value的NSPointerFunctionsOptions类型方便存储;
- (void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g {
    [self.weakCache setObject:obj forKey:[[key mutableCopy] copy]];
}
- (id)objectForKey:(id)key {
    id obj = [self.weakCache objectForKey:key];
    return obj;
}

当从内存中去查找缓存的图片时,会用图片的key去memCache中查找,若查找到内存中存在图片,则返回给用户回调使用;若未查找到图片,则进行接下来的步骤,从磁盘中读取!

 

  • 查询磁盘中的图片
- (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;
    }

// 去除stringByDeletingPathExtension扩展名的路径
    data = [NSData dataWithContentsOfFile:defaultPath.stringByDeletingPathExtension options:self.config.diskCacheReadingOptions error:nil];
    if (data) {
        return data;
    }

// 在自定义的customPaths路径中查找
    NSArray<NSString *> *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;
        }

        imageData = [NSData dataWith
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值