JSONSerialization.jsonObject导致swift 4.0和4.2中的内存泄漏

问题描述 投票:2回答:1

我正在开发一个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。

有没有人遇到过这个问题?有解决方案吗?

ios swift memory-leaks nsjsonserialization
1个回答
0
投票

也许我可以帮忙。我一直在研究一个具有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)

    }

}

再次调试后,我看到有一些峰值,但内存稳定。

© www.soinside.com 2019 - 2024. All rights reserved.