【问题标题】:Runtime error handling in SwiftSwift 中的运行时错误处理
【发布时间】:2014-12-20 03:29:32
【问题描述】:

我完全清楚 Swift 没有用于捕获异常的 try/catch 机制(好的,Swift 2.0 现在支持它们)。我也明白许多 API 方法会返回一个 NSError ,如果出现问题,该错误对象将被填充。所以请不要指点我这个问题:Error-Handling in Swift-Language

但这仍然没有解释如何对您自己的代码中的运行时错误做出反应,例如数组越界访问或强制解包 nil 的可选值。例如:

var test: String?
test = nil
println(test!) //oops!

var arr = [0,1,2]
for i = 0...3 {
    println(arr[i]) //oops!
}

每个程序员偶尔都会犯这样的错误,应该有办法至少记录它们以供以后分析。在调试时,Xcode 可以向我们展示这些,但如果这发生在最终用户或 beta 测试人员身上怎么办?在纯 C 中有信号处理,它也可以在 Objective-C 中使用。斯威夫特有这样的东西吗?在应用终止之前输入的集中回调?

更新:

让我换个说法:在大型项目中,在每个循环和强制展开时手动检查上述错误是不可行的。当运行时错误最终确实发生时,是否会调用诸如 Objective C 的段错误处理或 NSSetUncaughtExceptionHandler 之类的回调,以便可以将错误与崩溃的堆栈跟踪一起记录/通过电子邮件发送?

【问题讨论】:

    标签: exception swift runtime signals handle


    【解决方案1】:

    编辑:此答案未随 swift 2.0 更新。由于 swift 现在有错误处理,我没有更新以下答案。 swift 3.0 将来会更新错误处理的某些方面。你可以关注这个答案Error-Handling in Swift-Language

    Swift 被制作成typeSafe 语言。它在编译时出错,而不是在运行时等待导致。

    在第一个示例中,您使用的是Optional

    var test: String?
    

    首先了解optional的含义。当你指定optional时你说它可能是nil or have no value。现在当你解开test你说我知道这个值是not nil。请解开它我我很确定。所以你有责任看看它在哪里nil。如果你不确定,那么你应该在这里使用可选绑定。当你不确定值时,总是使用 if 条件 unwrrapping

      if let notNilTest = test {
        //use notNilTest
      }
      else{
       //handle error
      }
    

    在第二个示例中,进行运行时异常处理应该是有意义的,但是您可以通过具有计数的if 条件轻松获得它。因此,在第二个示例中,作为开发人员,您应该使用 if 条件来获得数组的count

    来自快速指南:

    如果您尝试使用下标语法来检索或设置一个值 超出数组现有边界的索引,您将触发 运行时错误。但是,您可以在之前检查索引是否有效 通过将其与数组的 count 属性进行比较来使用它。除非当 count 为 0(表示数组为空),数组中最大的有效索引 数组将始终为 count - 1,因为数组的索引从零开始。

    他们清楚地提到了这一点,你应该注意这些事情,以减少你的代码错误。他们提供了一些东西,我们应该知道如何使用这些东西。

    【讨论】:

    • 这基本上意味着“你通过不做任何错误来处理错误”。这些例子非常简单,但在一个 50000 行的项目中,检查每个循环和强制展开的那些是不可行或不漂亮的。最终会发生运行时错误。然后呢?
    • 如果你在实践中没有使用这些东西,那么在 try catch 块上处理所有这些异常是非常脆弱和不切实际的。你使用 try/catch 或 if 条件。还有很多错误由于错误处理及其有效的争议点而发生。但采取预防措施总是更好
    • Objective C 具有信号处理和 NSSetUncaughtExceptionHandler。 Java 有 Thread.setDefaultUncaughtExceptionHandler。 C# 有 AppDomain.UnhandledException。请注意,这些不是 try/catch 块,而是集中处理程序,以防万一一切都失败。为什么 Swift 中没有这样的东西?它并不比 Java 或 C# 更安全
    • @OrlinGeorgiev - 我也尝试过,但我找不到捕捉快速运行时错误的方法。但 crittercism 确实捕捉到了它。你找到解决办法了吗?
    • @OrlinGeorgiev - 我相信一定有一种方法,因为 Crittercism 报告了我的 swift 应用程序中发生的所有崩溃。
    【解决方案2】:

    考虑使用一个保护语句而不是多个 if let。

    var arr = [0,1,2]
    for i = 0...3 {
        Guard arr[i] != nil else {
            Continue
        }
        println(arr[i]) //oops!
    }
    

    或者代替

    if let x = some value {
        If let y = someOtherVal {
            If let z = yetanotherVal {
                Product = x * y* z
            }
        }
    }
    

    不如:

    Let x = someVal
    Let y = someOtherVal
    Let z = yetAnotherVal
    
    Guard x != nil,
      y != nil,
      z != nil
    Else {
      Return
    }
    
    Product = x * y * z
    

    【讨论】:

      猜你喜欢
      • 2016-02-05
      • 2015-12-06
      • 2016-03-31
      • 1970-01-01
      • 2015-02-21
      • 2017-09-05
      • 1970-01-01
      • 2020-09-19
      • 2016-03-18
      相关资源
      最近更新 更多