尽管进行了try?施工,我还是在我的应用程序中发现了一些崩溃。记录的 firebase crashlytics
Fatal Exception: NSInvalidArgumentException
Invalid number value (infinite) in JSON write
Run Code Online (Sandbox Code Playgroud)
这是一个测试示例
let avgSpeed = 0.1 / 0
print(avgSpeed)
let data = ["average_speed" : avgSpeed]
if let body = try? JSONSerialization.data(withJSONObject: [data]) {
print("success")
} else {
print("unable to make body for call")
}
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
iOS 13,快速 4
try?不捕获异常。它捕获抛出的错误。这些在 Swift 中是不同的。异常处于 Objective-C 级别,并且根本无法被 Swift捕获(在大多数情况下,它们也无法在 ObjC 中安全地捕获,但这是一个不同的讨论)。
这种情况下的解决方案是使用 JSONEncoder 而不是 JSONSerialization。JSONEncoder 是一个纯 Swift 系统。JSONSerialization 是从 ObjC 桥接的。
let body = try? JSONEncoder().encode([data])
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅处理错误:
Swift 中的错误处理类似于其他语言中的异常处理,使用 try、catch 和 throw 关键字。与许多语言(包括 Objective-C)中的异常处理不同,Swift 中的错误处理不涉及展开调用堆栈,这是一个计算成本很高的过程。因此,throw 语句的性能特征与 return 语句的性能特征相当。
如果您想使用 JSONSerialization,重要的是要认识到以这种方式调用它是一个编程错误。该异常旨在使程序崩溃(即使在 ObjC 中)。编写此代码的正确方法是:
if JSONSerialization.isValidJSONObject([data]), // <=== first, check it is valid
let body = try? JSONSerialization.data(withJSONObject: [data]) {
print("success")
} else {
print("unable to make body for call")
}
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅文档:
如果 obj 不会生成有效的 JSON,则会引发异常。此异常在解析之前抛出,表示编程错误,而不是内部错误。在使用 isValidJSONObject(_:) 调用此方法之前,您应该检查输入是否会生成有效的 JSON。
JSONSerialization 抛出的错误只是表明序列化程序中的内部错误,而不是尝试对无效对象进行编码:
错误
如果发生内部错误,返回时包含一个 NSError 对象,其代码 NSPropertyListWriteInvalidError 描述了问题。
| 归档时间: |
|
| 查看次数: |
201 次 |
| 最近记录: |