如何从catch子句中的NSError获取userInfo

gan*_*ogo 9 error-handling swift swift2

如果我有投掷方法,如下:

func doSomethingWithString(string:String) throws {
  guard string.characters.count > 0 else {
    throw NSError(domain: "CustomErrorDomain", code: 42, userInfo: ["foo" : "bar"])
  }
  // Do something with string...
}
Run Code Online (Sandbox Code Playgroud)

然后我尝试调用它并阅读userInfo:

do {
  try doSomethingWithString("")
} catch let error as NSError {
  print(error.domain)
  print(error.code)
  print(error.userInfo)
}
Run Code Online (Sandbox Code Playgroud)

...它以空字典的形式返回,(但域名和代码已正确填充):

CustomErrorDomain
42
[:]
Run Code Online (Sandbox Code Playgroud)

但如果我加上这个额外的步骤:

do {
  try doSomethingWithString("")
} catch let e {
  let error = e as NSError
  print(error.domain)
  print(error.code)
  print(error.userInfo)
}
Run Code Online (Sandbox Code Playgroud)

...有用:

CustomErrorDomain
42
[foo: bar]
Run Code Online (Sandbox Code Playgroud)

有人知道为什么会这样吗?

仅供参考 - 我正在使用Xcode 7 beta 2(7A121l)

Cod*_*ent 4

这是一个错误,已在 Xcode 7 Beta 4 中修复。以下是发行说明的摘录(PDF,第 15 页):

\n\n
\n

Xcode 7 beta 4 \xe2\x80\x94 Swift 2.0 和 Objective-C 中已解决的问题

\n\n

当在 Swift 中抛出对 NSError 实例的引用时,如果原始 NSError 被捕获为 NSError,则 Swift 运行时不会再丢失它。Swift 运行时现在保留原始 NSError 的标识。例如,这个断言现在成立:

\n
\n\n
 let e = NSError(...)\n do {\n   throw e\n } catch let e2 as NSError {\n   assert(e === e2)\n }\n
Run Code Online (Sandbox Code Playgroud)\n