【问题标题】:Is there any way I can catch assertions in Swift?有什么方法可以在 Swift 中捕获断言?
【发布时间】:2014-07-23 02:51:50
【问题描述】:

似乎 Swift 没有类似 C#/Java 的异常,而是使用断言。但是,这本书说在生产环境中,他们会立即使应用程序崩溃。没有办法解决吗?那么单元测试呢,我如何测试某个函数是否断言它获得了正确的输入值?

【问题讨论】:

  • 这本书在哪里说,他们会在生产中崩溃?我读过它,因为它们不应该在生产中使用并且在开发中使您的应用崩溃。
  • 建议只在开发过程中使用断言,因为它们会终止应用程序。在这种情况下不应该使用可选项(其中可选项包含一个值或 nil 显示该值缺失),然后在该值存在时继续使用标准防御性编程吗?
  • 在 Swift 中,对于“发布”版本(使用例如 swift -O 编译),断言似乎被忽略了。所以不幸的是,他们似乎不会在生产环境中立即使应用程序崩溃。
  • 您可以按照本文中的说明为 Swift 添加 try-catch 支持:medium.com/@_willfalcon/adding-try-catch-to-swift-71ab27bcb5b8

标签: exception try-catch assert swift


【解决方案1】:

正如您所提到的,断言会使您的应用在调试或生产中崩溃。它们的设计目的不是像 Java/C# 异常那样工作。他们唯一真正的目的是:

只要条件有可能为假,就使用断言, 但必须绝对正确才能让您的代码继续 执行。 ...在可能出现无效条件的情况下,断言 是确保突出显示此类条件的有效方法 在开发过程中,在您的应用发布之前注意到。

由于您可以在 Swift 中使用 Cocoa 类,因此您仍然可以将 NSException 用于您的代码可以处理的特殊事情。

【讨论】:

  • 你有在 Swift 中如何做到这一点的例子吗?例如,我如何在 Swift 程序中抛出/捕获NSException
  • @BradDwyer 异常不仅仅返回一个简单的值。它们允许在调用堆栈的更高层处理异常,并提供仅捕获特定类型(即:更具体的错误)并使用“finally”子句。简单地返回一个错误对象(即:NSException)似乎是一个巨大的时间倒退。也许这并没有成为 v1.0 Swift 规范,但根本没有错误/异常机制似乎过于简单。
  • @Marchy 异常即使在 Obj-C 中也被“弃用”。每个人都应该使用NSError * 返回参数。异常的问题是它们有时会破坏良好的 MRC/ARC 内存模型,因为某些对象不调用 release。这意味着抛出和捕获异常会导致泄漏。
  • @Sulthan 为什么你认为 NSException 被弃用了?在 ObjC 和 Swift 语言文档的预发布文档中,它仍然被列为活动状态。 NSException 的问题一直是每种语言的异常问题所在。程序员使用它们来报告预期的错误或非常低效的流控制。它们旨在用于程序员没有预料到的特殊情况。 NSError 应该用于程序员确实期望的错误情况。
  • 我写了一个快速包装器,它为 Swift 启用 try-catch。在这里查看。 medium.com/swift-programming/…
【解决方案2】:

您可以按照本文中的说明为 Swift 添加 try-catch 支持:https://medium.com/@_willfalcon/adding-try-catch-to-swift-71ab27bcb5b8

基本上,它是 Obj-C try-catch 的包装器

【讨论】:

    【解决方案3】:

    从 Apple 书籍中,似乎应该使用枚举来处理 Swift 编程语言的错误。

    这是书中的一个例子。

    enum ServerResponse {
        case Result(String, String)
        case Error(String)
    }
    
    let success = ServerResponse.Result("6:00 am", "8:09 pm")
    let failure = ServerResponse.Error("Out of cheese.")
    
    switch success {
    case let .Result(sunrise, sunset):
        let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)."
    case let .Error(error):
        let serverResponse = "Failure...  \(error)"
    }
    

    来自:Apple Inc. “Swift 编程语言”。电子书。 https://itun.es/br/jEUH0.l

    对于意外错误,您应该使用lfalin 指出的 NSException

    【讨论】:

    • 没有任何地方说这是处理错误的好方法。它看起来更像是一个使用枚举的人为示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 2015-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多