PersistentCacheKit 0.4.2

PersistentCacheKit 0.4.2

David Beck 维护。



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作为缓存。或者,为了禁用持久化存储并仅使用内存缓存,他们可以传人一个没有任何后端存储的缓存。最后,如果他们想使用自定义存储方法,他们可以传递一个包含他们特定存储类的缓存。