PersistentCacheKit
一个用于将项目缓存在文件系统的 Swift 库(默认使用 SQLite)。
PersistentCache
是一种对特定类型的键和值缓存存储的视图。它将使用内存缓存来快速访问常用数据。因为内存缓存具有特定的类型,所以它可能比更通用的缓存实现更快。
PersistentCache
可以选择性地使用一个 CacheStorage
来从应用的启动或内存警告中持久化它的数据。默认设置为共享的 SQLiteCacheStorage
。持久存储将所有键转换为字符串,将所有值转换为数据使用 Codable
。
并发
缓存和存储是线程安全的。每个缓存都使用它自己的串行队列,这样不同的缓存就可以在不失去内部一致性的情况下独立操作。当一个缓存只需要访问它的内存存储时,它可以与其他缓存并行地进行。当它需要访问存储时,它将进行串行访问。尽可能异步地进行工作。例如,在设置新值时,内存缓存立即更新,以确保后续对数据的请求是正确的,但会异步写入磁盘。
使用
struct Message: Codable {
var id: UUID = UUID()
var createdAt: Date = Date()
var body: String = ""
}
let cache = PersistentCache<UUID, [Message]>()
let roomID = UUID()
if let cached = cache[roomID] {
// show cached messages
} else {
// load them some expensive way
cache[roomID] = (0..<10).map({ Message(body: String($0)) })
}
创建缓存
通常情况下,您只需要指定键和值类型。但您也可以包括缓存存储和命名空间。
let cache = PersistentCache<UUID, [Message]>(storage: customStorage, namespace: "com.example�.app")
使用自定义存储可以是有用的,无论是为了使用不同的存储方法,还是为了在多个缓存之间并行存储。
命名空间对于避免多个缓存之间的名称冲突非常有用。
访问值
访问缓存数据的最简单方法是使用下标。
let value = cache[key]
cache[key] = value
如果可能的话,这将使用内存缓存,或者如果需要,访问存储。
您还可以使用缓存项访问数据
let value = cache[item: key]
cache[item: key] = Item(value, expiresIn: 60 * 60)
这主要是有价值的,可以为值设置过期日期。常规的索引将忽略已过期的项,因此在实践中,直接获取项通常是很少需要的。
存在各种获取方法,可以对缓存进行查找或更新
cache.fetch(key, fallback: { value })
这是围绕索引访问的基本包装器。其他获取方法以异步方式执行查找
cache.fetch(key, queue: .main) { value in
// use value (possibly nil)
}
cache.fetch(key, queue: .main, fallback: { value }) { value in
// use value (never nil)
}
这些方法将首先检查内存缓存中的数据,如果存在,则立即调用完成而不派遣到其他线程。但是,如果需要,它们将在后台队列上异步从存储加载数据。
模式
在创建时将缓存传递进来可能是一个很好的测试和灵活性的主意。
class Foo {
let cache: PersistentCache<UUID, String>?
init(cache: PersistentCache<UUID, String>? = PersistentCache(namespace: "Foo")) {
self.cache = cache
}
}
let fooA = Foo(cache: PersistentCache(storage: custom))
let fooA = Foo(cache: PersistentCache(storage: nil))
let fooB = Foo(cache: nil)
请注意,缓存是可选的。如果测试或框架的用户想要完全禁用缓存,他们可以传递nil作为缓存。或者,为了禁用持久化存储并仅使用内存缓存,他们可以传人一个没有任何后端存储的缓存。最后,如果他们想使用自定义存储方法,他们可以传递一个包含他们特定存储类的缓存。