在文件操作中复制文件的 API 在 Swift 1 中使用的是和 Objective-C 类似的 NSError 指针方式。
func copyItemAtPath(_ srcPath: String, toPath dstPath: String, error: NSErrorPointer)
而在 Swift 2 中,变为了 throws。
func copyItemAtPath(_ srcPath: String, toPath dstPath: String) throws
使用时,Swift 1 中我们需要创建并传入 NSError 的指针,在方法调用后检查指针的内容,来判断是否成功。
let fileManager = NSFileManager.defaultManager()
var error: NSError?
fileManager.copyItemAtPath(srcPath, toPath: dstPath, error: &error)
if error != nil {
// 发生了错误
} else {
// 复制成功
}
在实践中,因为这个 API 仅会在极其特定的条件下(比如磁盘空间不足)会出错,所以开发者为了方便,有时会直接传入 nil 来忽视掉这个错误。
忽略错误
let fileManager = NSFileManager.defaultManager()
// 不关心是否发生错误
fileManager.copyItemAtPath(srcPath, toPath: dstPath, error: nil)
这种做法无形中降低了应用的可靠性以及从错误中恢复的能力。为了解决这个问题,Swift 2 中在编译器层级就对 throws 进行了限定。被标记为 throws 的 API,我们需要完整的 try catch 来捕获可能的异常,否则无法编译通过。
编译失败
let fileManager = NSFileManager.defaultManager()
do {
try fileManager.copyItemAtPath(srcPath, toPath: dstPath)
} catch let error as NSError {
// 发生了错误
print(error.localizedDescription)
}
对于非 Cocoa 框架的 API,我们也可以通过声明 ErrorType 并在出错时进行 throw 操作。这为错误处理提供了统一的处理出口,有益于提高应用质量。