在 WWDC 2021 视频中,使用 Swift actors 保护可变状态,他们提供了以下代码片段:
actor ImageDownloader {
private var cache: [URL: Image] = [:]
func image(from url: URL) async throws -> Image? {
if let cached = cache[url] {
return cached
}
let image = try await downloadImage(from: url)
cache[url] = cache[url, default: image]
return cache[url]
}
func downloadImage(from url: URL) async throws -> Image { ... }
}
问题在于演员提供了可重入性,因此cache [url,默认值:image]
引用有效地确保即使由于某些竞争导致执行冗余请求,您至少会在继续之后检查演员的缓存,确保您获取冗余请求的相同图像。
而在那个视频中,他们说:
更好的解决方案是完全避免冗余下载。我们已经将该解决方案放入与该视频相关联的代码中。
但是网站上没有与该视频相关联的代码。那么更好的解决方案是什么呢?
我理解演员的可重入性的好处(如在SE-0306中讨论的那样)。例如,如果下载四个图像,则不想禁止可重入性,从而失去下载的并发性。我们实际上希望等待特定图像的重复先前请求的结果(如果有),如果没有,则开始新的downloadImage
。