我有一个变量的释放问题:缓存
这是来自教程Reusable Image Cache in Swift
错误:
致命错误:尝试读取无主引用,但对象 0x280208080 已被释放致命错误:尝试读取无主引用,但对象 0x280208080 已被释放
代码:
final class ImageLoader {
private let cache = ImageCache()
func loadImage(from url: URL) -> AnyPublisher<UIImage?, Never> {
if let image = cache[url] {
return Just(image).eraseToAnyPublisher()
}
return URLSession.shared.dataTaskPublisher(for: url)
.map { UIImage(data: $0.data) }
.catch { error in return Just(nil) }
.handleEvents(receiveOutput: {[unowned self] image in
guard let image = image else { return }
self.cache[url] = image
})
.subscribe(on: DispatchQueue.global(qos: .background))
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
}
}
Run Code Online (Sandbox Code Playgroud)
这个错误有一个非常简单的解释:
当 URLSession 完成它的工作时,ImageLoader 的实例不存在,因为没有人保留对它的引用。当您只是在函数作用域变量中创建该实例时,可能会发生这种情况。(也许在像 viewDidLoad 这样的函数中)。这个崩溃很有用,因为它表明加载程序以错误的方式使用。如果使用弱 self 或捕获整个实例,则不会发生崩溃,但是您将有很多 ImageLoader 和自己的缓存,其中有一张图像。因此,就其意义而言没有缓存。
为了解决这个问题,在创建 ImageLoader 实例之后,您应该将对其的引用保留在消费它的类/结构变量中,并将其传递给另一个需要相同缓存的消费者。(依赖注入技术是一个很好的方法)。因此,一个包含一定数量项目的缓存将存在并有效。
或者最简单的方法是创建一个 ImageLoader 的共享实例并仅使用它,因此它也保证它的一个实例与一个填充的缓存。
| 归档时间: |
|
| 查看次数: |
4479 次 |
| 最近记录: |