Swift惯用错误检查

mik*_*ejd 3 error-handling idioms nserror swift

假设您有这样的函数:

func getSomething(error: NSErrorPointer) -> Something
Run Code Online (Sandbox Code Playgroud)

你通常这样使用它:

var error : NSError? = nil
let a = getSomething(&error)
Run Code Online (Sandbox Code Playgroud)

在这里检查错误的惯用方法是什么?更具体的问题:

  1. 如果error == nil我们可以假设a永远不会为零,反之亦然?
  2. 我们应该先检查一下:( error为了它的无效)或a(确认它不是零)?
  3. a != nil && error != nil在某些情况下可以是真的吗?

谢谢!

Mar*_*n R 8

比较 "错误处理编程指南"中从方法返回的处理错误对象:

重要说明:方法的返回值表示成功或失败.虽然在Cocoa错误域中间接返回错误对象的Cocoa方法可以保证返回这样的对象,如果方法通过直接返回nil或NO来指示失败,你应该在尝试对之做任何事情之前检查返回值为nil或NO. NSError对象.

因此,对于Cocoa/Cocoa Touch方法,您应该首先检查返回值.保证error != nil如果方法失败,但是error == nil如果方法成功则没有明确保证.

例子:

JSON序列化

var error : NSError?
if let jsonObj = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: &error) {
    // success
} else {
    // failure
    println("Invalid JSON data: \(error!.localizedDescription)")
}
Run Code Online (Sandbox Code Playgroud)

核心数据获取请求

var error : NSError?
if let result = context.executeFetchRequest(request, error: &error) {
    // success, result has zero or more elements
} else {
    // failure
    println("Fetch failed: \(error!.localizedDescription)")
}
Run Code Online (Sandbox Code Playgroud)

复制文件

var error : NSError?
if !NSFileManager.defaultManager().copyItemAtPath(srcPath, toPath: dstPath, error: &error) {
    println("Cannot copy file: \(error!.localizedDescription)")
}
Run Code Online (Sandbox Code Playgroud)

当然,您可以为自己的功能定义自己的规则,但我会遵循相同的Apple指南.


更新:从Swift 2开始,产生错误的Cocoa方法被转换为抛出错误的Swift函数,并且必须使用try- 来处理此错误catch.以下是上面示例的Swift 2版本:

JSON序列化

do {
    let jsonObj = try NSJSONSerialization.JSONObjectWithData(jsonData, options: [])
    // success
} catch let error as NSError {
    // failure
    print("Invalid JSON data: \(error.localizedDescription)")
}
Run Code Online (Sandbox Code Playgroud)

核心数据获取请求

do {
    let result = try context.executeFetchRequest(request)
    // success, result has zero or more elements
} catch let error as NSError {
    // failure
    print("Fetch failed: \(error.localizedDescription)")
}
Run Code Online (Sandbox Code Playgroud)

复制文件

do {
    try NSFileManager.defaultManager().copyItemAtPath(srcPath, toPath: dstPath)
} catch let error as NSError {
    print("Cannot copy file: \(error.localizedDescription)")
} 
Run Code Online (Sandbox Code Playgroud)

  • @mikejd:我想*我前段时间听到/读过一个函数可能会将错误指针传递给另一个失败的低级函数并设置错误.如果更高级别的函数选择忽略较低级别函数的此错误并返回成功,则仍会设置错误对象.但我不是百分百肯定,我实际上没有观察到这种情况. (2认同)