【问题标题】:Incorrect try/catch behavior in Xcode 7 beta 3's Swift 2?Xcode 7 beta 3 的 Swift 2 中的 try/catch 行为不正确?
【发布时间】:2015-10-19 01:13:50
【问题描述】:

我对一些使用 Xcode 7 beta 3 编译的 Swift 2 代码有疑问。

我有一个类(见下文),它有一个初始化器,它接受一个可以抛出的函数 f。如果 f 不抛出,则应将成员变量 (self.result) 设置为封装 f 返回值的枚举实例。如果 f 确实抛出,则 self.result 应设置为指示该值不存在的枚举实例。在初始化程序的末尾,self.result 不应为 nil。我已经检查了 f 不抛出的情况,并且行为是正确的。但是,在 f 确实抛出的情况下, self.result 在初始化程序的末尾是 nil (触发了断言)。如果我在调试器中单步执行,我会看到 self.result 似乎立即被设置,然后闪回为 nil。

(注意:您可能会建议我将没有结果表示为 nil,而不是包装在枚举中。但是,我需要对 f 的结果尚未计算但已成功计算的场景进行建模,或者尝试计算结果但失败了。因此是枚举。)

我是否误解了 Swift 2 的错误处理机制?或者,编译器/调试器等行为是否不正确?

提前致谢。

internal enum Result<T> {
  case Value(T)
  case None
}

public final class MyClass<T> {

  internal var result: Result<T>? = nil

  private init(f: () throws -> T) {
    let queueName = “some.string”
    let queue = dispatch_queue_create(queueName, DISPATCH_QUEUE_CONCURRENT)
    dispatch_async(queue) {
      do {
        let value = try f()
        self.result = .Value(value)
      }
      catch {
        self.result = .None
      }
      assert(self.result != nil, "Result must have value before block returns.")
    }
  }
}

【问题讨论】:

  • 克里斯,这是因为,控制将立即从 dispatch_async 中出来,甚至在调用 do..catch 之前,断言就被调用了。
  • @nshebbar:不,在调度块中,语句是按顺序执行的。
  • 谢谢两位,但 Martin R 的回答是正确的。
  • 哦,我应该更仔细地看一下!,我以为断言在异步块之外!

标签: ios xcode swift


【解决方案1】:

self.result = .None

左边是一个可选 Result,因此.None on 右侧推断为Optional.None,语句 相当于

self.result = nil

你的意思可能是

self.result = Result.None

然后断言不再失败。或者, 使用不同的枚举值,例如case NoValue 在您的自定义 输入。

【讨论】:

  • 谢谢马丁!我完全忘记了 Optional.None 与 nil 相同。
猜你喜欢
  • 2015-10-17
  • 1970-01-01
  • 1970-01-01
  • 2015-10-24
  • 1970-01-01
  • 2015-09-24
  • 1970-01-01
  • 2015-11-16
  • 1970-01-01
相关资源
最近更新 更多