上一篇文章介绍了 KingFisher的下载流程这篇文章分析一下他的缓存策略.
当执行loadAndCacheimage的时候看到下载成功后会进行 缓存操作
image.png
这里用到的是一个ImageCache类
初始化方法
image.pngimagecache的初始化用到了内存存储器和磁盘存储器,
MemoryStorage
image.png这是定义了一个枚举,枚举里面定一个泛型类,泛型是Int和UIImage实现的一个接口 叫 CacheCostCalculable
这个接口的是计算缓存成本,类里面实现是由:
NSCache类:NSCache是苹果官方提供的缓存类,它的用法与NSMutableDictionary的用法很相似,NSCache在系统发出低内存通知时,会自动删减缓存。NSCache可以设置数量限制,通过countLimit与 totalCostLimit来限制cache的数量或者限制cost。当缓存的数量超过countLimit,或者cost之和超过totalCostLimit,NSCache会自动释放部分缓存。 NSCache实现有两个泛型一个是存储对象的key还有一个是StorageObject对象
StrorageObject:缓存对象的代表value代表数据,expiration代表缓存时间策略。
keys: 集合,所有缓存数据的key
cleanTimer: 每隔配置时间定时清理缓存
cacheDelegate: 缓存代理 NSCache的delegate,实现了NSCacheDelegate作用是通知内存管理器移除响应的key,
config: 结构体 这个结构体里包含 NSCache的配置类里面定义了countLimit(缓存个数限制) 和totalCostLimit (缓存大小限制)
还有 cleanInterval(每隔响应的实际戳则检查一遍过期的内存数据) 和 expiration (StorageExpiration类型的枚举 清理策略戳默认缓存5分钟内的数据,过期清楚由一个枚举定义可配置按天按秒到日期等各种策略)
removeExpired 方法timer的定时器执行的方法该方法会检查内存里的数据有没有过期,过期则移除,未过期则继续保留
remove(forKey key: String) removeAll 则是根据key移除缓存和移除所有缓存,这里面用到了线程互斥锁 NSLock,当对数据进行移除时需要锁上来保证数据的同步,defer一个很适合的使用场景就是用来做清理工作。当任务执行完毕,最后由他来进行解锁。
storeNoThrow和store:则是加入缓存方法实现很简单将StroneObject对象生成并用 cahce使用 setobject For key的方式来进行存储
value(forKey key: String) throws -> T? 读取使用storage的objectForkey操作将对象返回,如果对象已经过期则返回nil否则返回对象。
DiskStorage
磁盘缓存跟内存实现差不多不过他使用的不是NSCache而是Filemanager设置缓存对象的文件夹路径
而 Config 结构体 内容变为了
sizeLimit:缓存大小
expiration:过期时间
pathExtension:缓存项的首选扩展名。它将作为扩展名附加到文件名中默认值为“nil”,表示缓存文件不包含文件扩展名。
FileMeta
而StroneObject也变成了FileMeta结构体
里面定义了
lastAccessDate: 上次访问日期
estimatedExpirationDate: 预计到期日期
isDirectory:是否是文件夹
fileSize:文件大小
DisStoreage存储读取过程
存储过程.png 读取过程 删除文件获取所有缓存文件大小,而清楚所有文件就是调用removeAll方法
image.png
然后ImageCache类调用返回结果是CacheStoreResult的结构体里面有内存缓存回调结果和磁盘缓存回调结果
image.png image.png
网友评论