【发布时间】:2021-06-23 10:32:25
【问题描述】:
我有一个 JSONEncoder 编码一个 20mb 的文件,需要很长时间才能处理。如果它正在处理的数据发生变化,我想取消编码,并重新启动编码过程,但我想不出办法来做到这一点。有任何想法吗? 我可以再次调用 JSONEncoder.encode,但现在我将运行两个 30 秒的进程,并且内存和处理器开销增加一倍。 能取消上一个就太好了。
编辑:你们中的一些人要求查看我的编码器。这是我要说的导致最大瓶颈的原因...
func encode(to encoder: Encoder) throws {
try autoreleasepool {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(brush, forKey: .brush)
if encoder.coderType == CoderType.export {
let bezierPath = try NSKeyedUnarchiver.unarchivedObject(ofClass: UIBezierPath.self, from: beziersData)
let jsonData = try UIBezierPathSerialization.data(with: bezierPath, options: UIBezierPathWritingOptions.ignoreDrawingProperties)
let bezier = try? JSONDecoder().decode(DBBezier.self, from: jsonData)
try container.encodeIfPresent(bezier, forKey: .beziersData)
} else {
try container.encodeIfPresent(beziersData, forKey: .beziersData)
}
}
}
【问题讨论】:
-
将您的编码器封装在一个可取消的对象中,例如 NSOperation 或使用 Combine 可能吗?
-
您使用的是哪个版本的 Swift?
-
如果您的模型数据允许您这样做,您应该考虑在块/子任务中执行此操作,例如 20MB 分为 100 个块,您在开始之前在 for 循环中一个接一个地执行此过程您可以检查每个子任务是否需要继续(此编码过程是否取消?)。如果它被取消,您可以从该点返回,而无需编码所有数据并清理您正在进行的文件等。只要您一次性执行此操作,它一旦启动就无法取消。跨度>
-
@SalmanKhakwani 感谢您的回答。我正在使用 Swift 5
-
我也想知道,为什么 20mb 文件会导致性能问题。 JSONEncoder 不是你能得到的禁食,但仍然没有那么慢,20mb 应该是一个问题。您可能会考虑一种更快的替代方案,它可以在 1/10 的时间内从 20mb JSON 创建自定义表示,甚至更快。
标签: swift jsonencoder