ios - JSONSerialization.jsonObject 在 swift 4.0 和 4.2 中导致内存泄漏

标签 ios swift memory-leaks nsjsonserialization

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

相关文章:

ios - 如何快速制作多行表格 View 标题?

ios - 为什么 IBAction 抛出异常?

ios - 将 UIScrollView scrollIndicatorInsets 定位到边缘,没有间距?

ios - 制作单例的单个副本

swift - 类别位掩码冲突情况

swift - 看不到 UIView 的 UIView subview

java - 加载 Podcast 音频导致 Java 中出现 OutOfMemoryError

java - 除了堆转储和线程转储之外,查找 java.exe 进程的内容

python - 寻找一种方法来阻止这个基本程序中的内存泄漏

javascript - 使用 WKWebView Objective C 在 AngularJS 中表单发布