如何将 fatalError 消息保存到 iOS 崩溃日志中?

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

我有一个在 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 中实现相同的目标?

ios swift cocoa-touch
2个回答
0
投票

Swift 确实支持错误处理。您可以通过确认

Error
协议来创建自己的错误类型,或者使用现有的错误类型,然后通过调用
throw error
抛出错误。

但是 Swift 强制您向任何可能引发错误的代码添加错误处理。有多种方法可以快速处理错误。

  1. throws
    关键字应用于您的函数,这表明该函数在调用时可以抛出错误,并且该错误应由调用者处理。

    func canThrowErrors() throws -> String
    
  2. 使用

    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
    }
    
  3. 此外,您可以使用

    try?
    try!
    来抛出函数调用,以禁用错误传播并检索在出现错误和运行时断言时分别返回 nil 的可选结果。

通过强制您在编译时处理所有错误,Swift 可以避免任何未定义的运行时行为和调试噩梦。

我建议仅在无法从状态恢复而不使应用程序崩溃的情况下使用

fatalError
或任何其他运行时断言。不幸的是,没有办法处理来自
fatalError
的错误,因为它的使用仅适用于此类场景。此外,在崩溃日志中,您只会获得导致崩溃的行号,以获取有关崩溃原因的其他信息,我建议使用自定义日志记录或分析。


0
投票

我也在 Xcode 14 中解决了这个问题。 我认为你应该尝试在 release 模式下运行(无调试)。 您是否尝试在 release 模式下运行?

就我而言,它有效。

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