我正在开发一个 iOS 应用程序,使用 swift 4.0(4.2 有同样的问题)。
我给 Encodable 添加了一个扩展
extension Encodable{
func toDict() throws -> [String:Any]? {
let jsonEncoder = JSONEncoder()
let jsonData = try jsonEncoder.encode(self)
do{
return try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any]
}
catch{
return nil
}
}
}
我有一个 Encodable 类的实例,它的属性也属于 Encodable 类,我注意到当经常调用 instance.toDict()
时,我的应用程序使用的内存增加了很多。
即使我不使用返回的结果也是如此,如果我返回 nil 并忽略 JSONSerialization.jsonObject
的结果也是如此。
我确定是这一行导致了问题(忽略结果并返回 nil 仍然会导致问题并且注释该行并返回 nil 将停止内存增加。
内存随着时间的推移越来越多,toDict()
被调用的次数也越来越多,我最终在 10 分钟内使用了 400MB。
有人遇到过这个问题吗?有解决办法吗?
最佳答案
也许我能帮上忙。我一直在从事一个具有 Codable 类模型的项目。我以为一切正常,直到我意识到应用程序在尝试循环编码时由于内存问题(超过 1.2GB)而崩溃。
调试应用程序后,我发现问题出在 JSONEncoder 中,经过一些谷歌搜索后,我发现这是一个错误,我发现最有效的解决方案是使用 autoreleasepool。 See HERE
以我为例:
static func store<T: Encodable>(_ object: T, to directory: Directory, as fileName: String) throws {
do{
try autoreleasepool{
let url = getURL(for: directory).appendingPathComponent(fileName, isDirectory: false)
let encoder = JSONEncoder()
let data = try encoder.encode(object)
if FileManager.default.fileExists(atPath: url.path) {
try FileManager.default.removeItem(at: url)
}
FileManager.default.createFile(atPath: url.path, contents: data, attributes: nil)
}
}
catch {
throw(error)
}
}
再次调试后,我看到有一些峰值,但内存稳定。
关于ios - JSONSerialization.jsonObject 在 swift 4.0 和 4.2 中导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54234580/