Swift 惯用错误检查
Posted
技术标签:
【中文标题】Swift 惯用错误检查【英文标题】:Swift idiomatic error checking 【发布时间】:2015-06-05 17:05:20 【问题描述】:假设你有这样一个函数:
func getSomething(error: NSErrorPointer) -> Something
你通常这样使用它:
var error : NSError? = nil
let a = getSomething(&error)
在这里检查错误的惯用方法是什么?更具体的问题:
-
如果
error == nil
我们可以假设a
永远不会为零,反之亦然
反之亦然?
我们应该首先检查什么:error
(对于它的 nilness)或 a
(对于
确认它不是零)?
a != nil && error != nil
在某些情况下是真的吗?
谢谢!
【问题讨论】:
【参考方案1】:比较Handling Error Objects Returned From Methods 在《错误处理编程指南》中:
重要提示:成功或失败由 方法。虽然 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)")
核心数据获取请求
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)")
复制文件
var error : NSError?
if !NSFileManager.defaultManager().copyItemAtPath(srcPath, toPath: dstPath, error: &error)
println("Cannot copy file: \(error!.localizedDescription)")
当然你可以为你自己的函数定义你自己的规则, 但我会遵循相同的 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)")
核心数据获取请求
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)")
复制文件
do
try NSFileManager.defaultManager().copyItemAtPath(srcPath, toPath: dstPath)
catch let error as NSError
print("Cannot copy file: \(error.localizedDescription)")
【讨论】:
马丁,感谢您的出色回答!你知道这个逻辑背后的动机是什么吗?为什么要先检查返回值而不是错误? @mikejd:我认为前段时间我听说/读到一个函数可能会将错误指针传递给另一个失败并设置错误的低级函数。如果高层函数选择忽略低层函数的这个错误并返回成功,则仍然设置错误对象。但我不是 100% 确定,而且我还没有真正观察到这种情况。 嗯,这听起来很合理。【参考方案2】:如果一个函数返回一个可选值,即
func someFunc(someVar: String) -> NSData?
// some code
(可选意味着它可以返回一个 nil) 那么错误检查就很简单了
if let data = someFunc("someString")
// this means there was NO error as the function didn't return a nil
else
// This means there was an error
这个视频是一个很好的参考,可以快速检查和处理错误https://youtu.be/m8szaLqHVDs
【讨论】:
虽然nil
返回值可能是故障的一个很好的提示,但您也经常需要一个实际错误来了解究竟出了什么问题,不是吗?
这取决于并且非常主观。但是如果一个函数提供了 NSError 指针作为参数的可用性,那么你可以选择是否使用它。以上是关于Swift 惯用错误检查的主要内容,如果未能解决你的问题,请参考以下文章