我有一个在 Xcode 8.2.1 中用 Swift 2 编写的 iOS 应用程序,它是为 iOS 10.2 构建的。
我收到了来自 TestFlight 的许多崩溃报告,尽管有符号化,但没有一个崩溃日志显示除堆栈跟踪之外的任何程序状态(没有参数值、没有本地变量、没有堆对象等)。
...但在这些函数中,我可以看到可能会失败的代码(例如强制展开),但崩溃日志没有告诉我失败的位置或原因。
在 Xcode 中调试时,我可以使用
fatalError(message: String)
,在其中可以放置自己的消息,如 "functionFoo returned nil"
或 "variable bar == \"" + bar + "\""
,除非使用 TestFlight 或 App Store 部署时,fatalError
将被命中并且程序终止,但是message
值不会保存到崩溃日志中,因此毫无意义。
在其他环境中,例如 C#/.NET 和 Java,我可以简单地
throw new SomeExceptionType("my message")
并且所有信息都可以在我拥有的任何全局 catch(Exception)
处理程序中使用。
如何在 iOS / Swift 中实现相同的目标?
Swift 确实支持错误处理。您可以通过确认
Error
协议来创建自己的错误类型,或者使用现有的错误类型,然后通过调用 throw error
抛出错误。
但是 Swift 强制您向任何可能引发错误的代码添加错误处理。有多种方法可以快速处理错误。
将
throws
关键字应用于您的函数,这表明该函数在调用时可以抛出错误,并且该错误应由调用者处理。
func canThrowErrors() throws -> String
使用
throws
关键字调用方法时,必须在调用开头添加 try
关键字。所有这些 try
调用都应该通过将 throws
应用于方法来仅传播错误或包装在 do-catch 块中来处理:
do {
try canThrowErrors()
try canThrowOtherErrors()
} catch is SpecificError {
// handling only specific error type
} catch let error as SpecificError {
// catches only specific error for type
} catch {
// catches all errors
}
此外,您可以使用
try?
和 try!
来抛出函数调用,以禁用错误传播并检索在出现错误和运行时断言时分别返回 nil 的可选结果。
通过强制您在编译时处理所有错误,Swift 可以避免任何未定义的运行时行为和调试噩梦。
我建议仅在无法从状态恢复而不使应用程序崩溃的情况下使用
fatalError
或任何其他运行时断言。不幸的是,没有办法处理来自 fatalError
的错误,因为它的使用仅适用于此类场景。此外,在崩溃日志中,您只会获得导致崩溃的行号,以获取有关崩溃原因的其他信息,我建议使用自定义日志记录或分析。
我也在 Xcode 14 中解决了这个问题。 我认为你应该尝试在 release 模式下运行(无调试)。 您是否尝试在 release 模式下运行?
就我而言,它有效。