|
@@ -0,0 +1,152 @@
|
|
|
|
+## SDWebImage学习-SDImageCache
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+####问题
|
|
|
|
+
|
|
|
|
+缓存怎么设计的(整体结构、工作流)
|
|
|
|
+
|
|
|
|
+涉及哪些类,都是干什么的
|
|
|
|
+
|
|
|
|
+有哪些缓存规则和配置选项,怎么配置
|
|
|
|
+
|
|
|
|
+内存缓存和磁盘缓存分别是怎么工作的?
|
|
|
|
+
|
|
|
|
+缓存读取同步还是异步,能否取消缓存读取
|
|
|
|
+
|
|
|
|
+一、二级内存缓存怎么协作
|
|
|
|
+
|
|
|
|
+缓存的图片是否是已解码的?
|
|
|
|
+
|
|
|
|
+从缓存读取到的图片是解码后的吗?
|
|
|
|
+
|
|
|
|
+缓存文件的命名
|
|
|
|
+
|
|
|
|
+缓存读取如何保证线程安全
|
|
|
|
+
|
|
|
|
+内存警告怎么处理
|
|
|
|
+
|
|
|
|
+磁盘缓存目录
|
|
|
|
+
|
|
|
|
+缓存什么时候清除?
|
|
|
|
+
|
|
|
|
+缓存清除策略,按什么清除
|
|
|
|
+
|
|
|
|
+如何自定义缓存
|
|
|
|
+
|
|
|
|
+....
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+####一、SDImageCacheDefine
|
|
|
|
+主要是一些基础定义
|
|
|
|
+
|
|
|
|
+缓存类型枚举 SDImageCacheType
|
|
|
|
+
|
|
|
|
+一系列缓存操作Block ,SDImageCacheCheckCompletionBlock等
|
|
|
|
+
|
|
|
|
+缓存查询过程中的解码方法SDImageCacheDecodeImageData
|
|
|
|
+
|
|
|
|
+定义了核心协议-SDImageCache,自定义缓存时只要实现该协议的方法,可以通过SDImageCachesManager来注册管理多个缓存
|
|
|
|
+
|
|
|
|
+####二、SDImageCacheConfig
|
|
|
|
+1、配置信息和选项
|
|
|
|
+SDImageCacheConfigExpireType,用来计算图片的过期时间的选项
|
|
|
|
+
|
|
|
|
+2、列举一些属性
|
|
|
|
+```@property (assign, nonatomic) NSDataReadingOptions diskCacheReadingOptions;```
|
|
|
|
+
|
|
|
|
+关于NSDataReadingOptions有几个选项
|
|
|
|
+NSDataReadingUncached : 不要缓存,如果该文件只会读取一次,这个设置可以提高性能;
|
|
|
|
+NSDataReadingMappedIfSafe : 在保证安全的前提下使用mmap;
|
|
|
|
+NSDataReadingMappedAlways : 使用mmap;
|
|
|
|
+可以传入NSDataReadingMappedIfSafe,这样系统就不会把整个文件读进内存,而是用进程的内存虚拟地址空间去映射实际的文件中,mmap不会为文件分配物理内存,而是相当于将内存地址指向文件的磁盘地址。一定场景下可以用来解决内存暴涨问题,例如加载一个视频文件,如果一下子加载完整的视频文件,内存可能暴涨,采用mmap来优化,建立文件映射,就可以有效减少内存占用。
|
|
|
|
+
|
|
|
|
+```@property (assign, nonatomic) NSDataWritingOptions diskCacheWritingOptions;```
|
|
|
|
+ 将缓存写入磁盘时的写入选项,默认为`NSDataWritingAtomic`,但是可以设置为“NSDataWritingWithoutOverwriting”以防止覆盖现有文件
|
|
|
|
+
|
|
|
|
+ 支持自定义缓存类
|
|
|
|
+```@property (assign, nonatomic, nonnull) Class memoryCacheClass;
|
|
|
|
+ @property (assign ,nonatomic, nonnull) Class diskCacheClass;
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+####三、SDImageCache类
|
|
|
|
+
|
|
|
|
+1、基本组成
|
|
|
|
+缓存的核心类,只要管理内存缓存和磁盘缓存
|
|
|
|
+主要属性
|
|
|
|
+```
|
|
|
|
+// 一些缓存的选项
|
|
|
|
+@property (nonatomic, copy, nonnull, readonly) SDImageCacheConfig *config;
|
|
|
|
+
|
|
|
|
+// 内存缓存
|
|
|
|
+@property (nonatomic, strong, readonly, nonnull) id<SDMemoryCache> memoryCache;
|
|
|
|
+
|
|
|
|
+//配置对象
|
|
|
|
+@property (nonatomic, copy, nonnull, readonly) SDImageCacheConfig *config;
|
|
|
|
+
|
|
|
|
+ //磁盘缓存
|
|
|
|
+@property (nonatomic, strong, readonly, nonnull) id<SDDiskCache> diskCache;
|
|
|
|
+
|
|
|
|
+//缓存路径
|
|
|
|
+@property (nonatomic, copy, nonnull, readonly) NSString *diskCachePath;
|
|
|
|
+
|
|
|
|
+//附加磁盘缓存路径,app预加载缓存可以用这个
|
|
|
|
+@property (nonatomic, copy, nullable) SDImageCacheAdditionalCachePathBlock additionalCachePathBlock;
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+初始化方法
|
|
|
|
+可以指定命名空间和沙盒目录中,命名空间也就是保存图像的文件夹名字
|
|
|
|
+-initWithNamespace: diskCacheDirectory:
|
|
|
|
+
|
|
|
|
+一系列存储、查询、删除和清理缓存等操作接口
|
|
|
|
+缓存清理接口
|
|
|
|
+获取缓存相关信息接口
|
|
|
|
+
|
|
|
|
+SDImageCache扩展,遵循了SDImageCache协议
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+2、具体实现
|
|
|
|
+
|
|
|
|
+根据config的属性创建memoryCache和diskCache,同时也把config同步过去
|
|
|
|
+
|
|
|
|
+migrateDiskCacheDirectory操作,把旧文件夹的缓存移动到新文件夹路径下
|
|
|
|
+
|
|
|
|
+设置监听
|
|
|
|
+UIApplicationWillTerminateNotification
|
|
|
|
+UIApplicationDidEnterBackgroundNotification
|
|
|
|
+处理删除磁盘中过期的数据
|
|
|
|
+核心代码
|
|
|
|
+[self.diskCache removeExpiredData];
|
|
|
|
+
|
|
|
|
+1)读取磁盘缓存路径
|
|
|
|
+2)读取缓存超时类型,根据config.diskCacheExpireType,
|
|
|
|
+将 SDImageCacheConfigExpireType(图片的过期时间类型) 和 NSURLResourceKey做一个映射。也就是我们自己可以选择超时的判断标准,比如可以创建时间、修改时间或者访问时间是否超时来决定是否删除。
|
|
|
|
+3)调用文件夹遍历函数enumeratorAtURL:includingPropertiesForKeys:options:errorHandler:,过滤掉隐藏文件、resourceKeys指定便随URL预取的资源属性,这里指定了三个属性:是否是目录、过期类型、为文件分配的空间
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+ NSArray<NSString *> *resourceKeys = @[NSURLIsDirectoryKey, cacheContentDateKey, NSURLTotalFileAllocatedSizeKey];
|
|
|
|
+
|
|
|
|
+ NSDirectoryEnumerator *fileEnumerator = [self.fileManager enumeratorAtURL:diskCacheURL
|
|
|
|
+ includingPropertiesForKeys:resourceKeys
|
|
|
|
+ options:NSDirectoryEnumerationSkipsHiddenFiles
|
|
|
|
+ errorHandler:NULL];
|
|
|
|
+ ```
|
|
|
|
+ NSURLIsDirectoryKey 允许判断遍历到的URL所指对象是否是目录
|
|
|
|
+ NSDirectoryEnumerationSkipsHiddenFiles 跳过隐藏文件
|
|
|
|
+
|
|
|
|
+ 4)删除过期的图片
|
|
|
|
+
|
|
|
|
+ 5)在缓存目录下遍历图片时,除了把过期的缓存图片移除,还需要把未过期的图片添加到cacheFiles,用来进行后续的清理逻辑(存储文件属性resourceKeys,通过size判断)
|
|
|
|
+ 6)根据配置的SDImageCacheConfig.maxCacheSize判断是否超过大小,如果超过,需要对剩下的图片进行二次清理,直到缓存目录大小 小于等于 config.maxCacheSize/2
|
|
|
|
+
|
|
|
|
+ 缓存清除时机
|
|
|
|
+收到内存就警告: 清理内存缓存
|
|
|
|
+App将要被杀死: 清理磁盘缓存
|
|
|
|
+App进入后台: 在后台清理磁盘缓存
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+Caches Manager
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|