Kingfisher的的图片缓存有内存缓存和磁盘缓存两种,都是有ImageCache类负责;
ImageCache的功能:
- 缓存图片
- 检索图片
- 清理图片
1.缓存图片
缓存图片分为下面两种方式:
- 内存缓存
- 磁盘缓存
内存缓存
内存缓存是由NSCache完成的,具体实现设计是通过MemoryStroage枚举中的Backend 类实现;下面介绍内存缓存的Backend
Backend中两个重要的类型:
- StorageObject 储存的实体类
- Config 结构体可以理解储存的配置
StorageObject 指定了一个泛型类型T,这里一般用的是Image,还有缓存key以及StorageExpiration对象,一个过期的枚举。
Config 指定NSCache的最大字节数,一个StorageExpiration对象指定什么时候过期默认是(300s)过期,清理内存缓存的时间默认是(120s)。
MemoryStroage中的Backend通过config初始化,初始化了一个NSCache对象storage, 和一个定时器按照config中配置的时间定时清理过期的缓存;
提供的方法肯定有 store存储,valueforKey根据key来获取储存的实体。remove方法等方法;
磁盘缓存
磁盘缓存是通过DiskStorage枚举中的Backend类实现,跟磁盘缓存同样的结构。
磁盘缓存中有个两个中重要类型:
- FileMeta 类
- Config 结构体
FileMeta类中包括存储的url,上次访问的时间,过期时间,文件大小等;
Config结构体包括过期时间默认是7days, name, 文件操作fileManager, pathExtenstion 路径扩展等。文件路径directory
DiskStorage中的Backend指定的泛型T是遵守DataTransFormable;这里有点面向协议的味道了,Kingfisher中是Data遵守了该协议; Backend同样通过Config来初始化。然后就是通过congfig中的fileManager来进行一系列的文件存储和删除操作;在检索的时候用的了FileMeta通过fileMeta对象来计算文件是否过期,以及延长过期时间。还有一点缓存文件的名字是以文件的md5来命名的。
2.检索图片
从初始化方法中可以看出ImageCache 连接MemoryStroage和DiskStorage。
public init(memoryStorage: MemoryStorage.Backend<Image>,
diskStorage: DiskStorage.Backend<Data>) {
self.memoryStorage = memoryStorage
self.diskStorage = diskStorage
let ioQueueName = "com.onevcat.Kingfisher.ImageCache.ioQueue.\(UUID().uuidString)"
ioQueue = DispatchQueue(label: ioQueueName)
let notifications: [(Notification.Name, Selector)]
notifications = [
(UIApplication.didReceiveMemoryWarningNotification, #selector(clearMemoryCache)),
(UIApplication.willTerminateNotification, #selector(cleanExpiredDiskCache)),
(UIApplication.didEnterBackgroundNotification, #selector(backgroundCleanExpiredDiskCache))
]
notifications.forEach {
NotificationCenter.default.addObserver(self, selector: $0.1, name: $0.0, object: nil)
}
}
1.先从内存缓存中检索,再从磁盘中找,尾随闭包是Result<ImageCacheResult, KingfisherError>
public enum ImageCacheResult {
case disk(Image)
case memory(Image)
case none
public var image: Image? {
switch self {
case .disk(let image): return image
case .memory(let image): return image
case .none: return nil
}
}
public var cacheType: CacheType {
switch self {
case .disk: return .disk
case .memory: return .memory
case .none: return .none
}
}
}
3.清理图片
上面解释过情况内存缓存默认有一个120s的定时器,除了这个ImageCache监听了系统的三个通知,从上面ImageCache初始化中可以看出:在收到系统内存警告的时候清理内存缓存,在进入后台,以及终止程序的时候清理过期的磁盘缓存。
网友评论