SDWebImage

2018-06-22  本文已影响0人  帽子和五朵玫瑰

SDWebImage

https://www.jianshu.com/p/b3eff8304b37
https://www.jianshu.com/p/a33d5abf686b
SDWebImage

|—-SDWebImageCompat
处理不同平台(iOS、TV、OS、Watch)宏,以及根据文件名@2x、@3x进行图片处理和缩放

|—-SDWebImageOperation.h 添加cancel的delegate

+—-Cache

|——–SDImageCache 主要处理缓存逻辑,重点集中在:NSCache(Memory)、Disk读写、清理Old File

|——–SDImageCacheConfig
配置缓存参数:是否压缩、iCloud、InMemory、ReadingOption、时间和CacheSize

+—-Downloader

|——–SDWebImageDownloaderOperation 主要提供下载的Operation操作

|——–SDWebImageDownloader 提供下载管理入口

+—-Utils

|——–SDWebImageManager 提供外层管理cache和download入口

|——–SDWebImagePrefetcher 预处理获取Image,主要应用预加载的地方

+—-Categories

|——–NSData+ImageContentType 提供类型判断和ImageIO类型转换

|——–UIImage+GIF Data转UIImage(GIF)扩展

|——–UIImage+MultiFormat 提供BitMap或者未知类型的Data转UIImage扩展

|——–UIImage+WebP Data转WebP扩展

|——–UIImage+ForceDecode 解压操作

|——–UIView+WebCacheOperation 提供顶层关于取消和下载记录的扩展

+—-Decoder

|——–SDWebImageCodersManager 整体Coders的入口,提供是否可Coder和Coder转发

|——–SDWebImageCoder 主要说明Coder Delegate 需要实现的接口

|——–SDWebImageImageIOCoder PNG/JPEG的Encode和解压操作

|——–SDWebImageGIFCoder GIF的Coder操作

|——–SDWebImageWebPCoder WebP的Coder操作

|——–SDWebImageFrame 辅助类,主要在GIF等动态图使用

|——–SDWebImageCoderHelper 辅助类,包括方向、Gif图合成等

整体组件结构

SDWebImage.png

1、缓存部分解析

缓存部分逻辑主要是在SDImageCache,包括如下几个方面:

新增

删除

查询

缓存管理(过期)

SDWebImage的缓存中,主要走了一套NSCache管理内存和根据传入的Key转换MD5作为文件名存储。以及创建了一个IO操作的Queue进行管理IO操作。

这里重点注意,任何耗时:包括IO读写、转码等操作,都不应该放到主线程里面使用。

1、通过NSOperation管理queue任务
- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key done:(nullable SDCacheQueryCompletedBlock)doneBlock {
    if (!key) {
        if (doneBlock) {
            doneBlock(nil, nil, SDImageCacheTypeNone);
        }
        return nil;
    }

    // First check the in-memory cache...
    UIImage *image = [self imageFromMemoryCacheForKey:key];
    if (image) {
        NSData *diskData = nil;
        if (image.images) {
            diskData = [self diskImageDataBySearchingAllPathsForKey:key];
        }
        if (doneBlock) {
            doneBlock(image, diskData, SDImageCacheTypeMemory);
        }
        return nil;
    }

    NSOperation *operation = [NSOperation new];
    dispatch_async(self.ioQueue, ^{
        if (operation.isCancelled) {
            // do not call the completion if cancelled
            return;
        }

        @autoreleasepool {
            NSData *diskData = [self diskImageDataBySearchingAllPathsForKey:key];
            UIImage *diskImage = [self diskImageForKey:key];
            if (diskImage && self.config.shouldCacheImagesInMemory) {
                NSUInteger cost = SDCacheCostForImage(diskImage);
                [self.memCache setObject:diskImage forKey:key cost:cost];
            }

            if (doneBlock) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    doneBlock(diskImage, diskData, SDImageCacheTypeDisk);
                });
            }
        }
    });

    return operation;
}

查询缓存的时候,这里采用了NSOperation进行是否取消的操作,因为当下载/缓存内容过多时,毕定存在先后处理顺序的问题,这时候可能由于用户操作等需要取消当前缓存处理,那么 NSOperation 这里起的唯一作用就是提供取消操作。可以参考具体的Manager里面缓存调起逻辑。

上一篇下一篇

猜你喜欢

热点阅读