在 beginSheetModalForWindow 中尝试

do try in beginSheetModalForWindow

在 Swift 2.0 中,如果我执行以下操作:

panel.beginSheetModalForWindow(self.view.window!) { (result) in

  switch result {
  // Save was selected
  case NSFileHandlingPanelOKButton:
    self.writeFile(fileString, fileURL: panel.URL!)
    // something else was selected
  default:
    break
  }
}

使用如下函数,编译运行。

  func writeFile(fileString: String, fileURL: NSURL) {
    do {
      try fileString.writeToURL(fileURL, atomically: true, encoding: NSUTF8StringEncoding)
    } catch let error as NSError {
      fatalError("Error writing to file - \(error)")
    }
  }

但是,如果我像这样结合两者:

panel.beginSheetModalForWindow(self.view.window!) { (result) in
  switch result {
  // Save was selected
  case NSFileHandlingPanelOKButton:
    do {
      try fileString.writeToURL(fileURL, atomically: true, encoding: NSUTF8StringEncoding)
    } catch let error as NSError {
      fatalError("Error writing to file - \(error)")
    }
    // something else was selected
  default:
    break
  }
}

它不会编译。我收到一个编译器错误:

从“() throws ->”类型的抛出函数到非抛出函数类型“(Int) -> Void”的无效转换

为什么?

像这样添加默认的 catch 块:

do {
      try fileString.writeToURL(fileURL, atomically: true, encoding: NSUTF8StringEncoding)
} catch let error as NSError {
      fatalError("Error writing to file - \(error)")
} catch {

}

http://www.hackingwithswift.com/new-syntax-swift-2-error-handling-try-catch

我找到了答案(在新的 Apple Developer 论坛上)。

如果你这样做它会起作用:

panel.beginSheetModalForWindow(self.view.window!) { (result) in
  switch result {
  case NSFileHandlingPanelOKButton:
    // Save was selected
    do {
      try fileString.writeToURL(panel.URL!, atomically: true, encoding: NSUTF8StringEncoding)
    } catch let error as NSError {
      fatalError("Error writing to file : \(error)")
    } catch {
      fatalError("Error")
    }
  default:
    // something else was selected
    break
  }
}

问题是 "catch" 并不详尽,这导致抛出被传播到封闭函数(而不是 "throw")。