swift - 为什么 diskConfig.cachePathBlock 应该在这里重置为零?
问题描述
我在看源代码Kingfisher
。我在以下代码(源代码)中有一个问题:
为什么diskConfig.cachePathBlock
要nil
在 init 方法结束时重置?我想不通。
public convenience init(
name: String,
cacheDirectoryURL: URL?,
diskCachePathClosure: DiskCachePathClosure? = nil) throws
{
if name.isEmpty {
fatalError("[Kingfisher] You should specify a name for the cache. A cache with empty name is not permitted.")
}
let totalMemory = ProcessInfo.processInfo.physicalMemory
let costLimit = totalMemory / 4
let memoryStorage = MemoryStorage.Backend<Image>(config:
.init(totalCostLimit: (costLimit > Int.max) ? Int.max : Int(costLimit)))
var diskConfig = DiskStorage.Config(
name: name,
sizeLimit: 0,
directory: cacheDirectoryURL
)
if let closure = diskCachePathClosure {
diskConfig.cachePathBlock = closure
}
let diskStorage = try DiskStorage.Backend<Data>(config: diskConfig)
diskConfig.cachePathBlock = nil
self.init(memoryStorage: memoryStorage, diskStorage: diskStorage)
}
解决方案
不将该属性设置为 nil 会保持对传入闭包的强引用,并可能造成内存泄漏。将其设置为 nil 可以避免这种情况。
假设 nil 分配不存在,这是一个泄漏示例:
class CacheBuilder {
func createCache() -> ImageCache {
let cache = try! ImageCache(name: "Cache", cacheDirectoryURL: nil, diskCachePathClosure: self.path)
return cache
}
func path(_ url: URL, _ str: String) -> URL {
return url
}
deinit {
print("deinit") // is not called when Cache.init is done
}
}
class Cache {
let cache: ImageCache
init() {
let builder = CacheBuilder()
self.cache = builder.createCache()
}
}
推荐阅读
- javascript - 在我输入时过滤对象数组
- php - 将 Imagemagick 命令转换为 php imagick
- node.js - Parse 找不到用户记录,然后在尝试创建它时出错。我哪里做错了?
- javascript - 如何处理来自具有多种内容类型的外部 API 的响应
- android - 如何在选项卡式活动中更改不同的 URL 或视图?
- c# - 我的 C# dotnet 代码创建的 SQLite 数据库在哪里?(在 Mac 上)
- php - 如何将一条信息插入到已经存在的记录中?
- angular - 如何检查 ngFor 内部的条件
- php - 不识别表中的id
- spring - Spring Security 中的 Tomcat 错误(Spring + MySQL)