MENU

Swift 中的错误处理

Cover

错误处理是指程序对发生的错误或者异常作出响应并进行状态恢复的过程。除了对已经发生的异常或者错误进行处理之外,有时候还需要对自己代码中可能的错误或者异常行为进行抛出。只有抛出了错误信息,其他人才能对
其进行精准定位。所以,下面我们就来看下 Swift 中的错误处理。

一个需要进行错误处理的典型场景就是文件读取了。读取任务失败出错的原因有很多,例如:权限不够、文件路径错误、或者文件编码格式不兼容等等。开发者需要区分这些错误中那些是能够解决而那些是不能解决并且需要告知用户原因。

在 Swift 中, 错误均由遵循 Error 协议的类型的值表示。

如果你使用 if-else 语法来处理上面读取文件中可能出现的错误和异常的话,那么代码大致是这样的:

func readFiles(path:String) -> String {
    if fileNotFound {
        print(“fileNotFound”)
    } else if fileNotReadable {
        print(“fileNotReadable”)
    } else if fileSizeIsTooHigh {
        print(“fileSizeIsTooHigh”)
    }
    
    return “Data from file”
}

在这里,如果我们希望控制权回转到上面函数调用处,并且告知调用者具体的错误类型,那么就需要在代码中将错误抛出。

Error Handling 不仅仅只是上面 if-else 方式的一种改写,它还能对错误信息作出响应和处理。

Swift 中的枚举类型非常适合对一组错误情形进行建模,其中的枚举值足够对错误信息完成初步描述。另外,该枚举类型还要遵循 Error 协议。

enum ErrorsToThrow: Error {
    case fileNotFound
    case fileNotReadable
    case fileSizeIsTooHigh
}

错误抛出函数的设计

如下所示,只需在函数声明的参数后加上 throw 关键词就能为函数加上异常抛出的能力。另外,函数自身并不会持有该错误,而是将其抛出后等待 do-try 函数块捕获并处理。

func canThrowErrors() throws -> String
func cannotThrowErrors() -> String

下面,我们就重写上面的文件读取函数 readFiles(path:)

func readFiles(path:String) throws ->String {
    if fileNotFound {
        throw ErrorsToThrow.fileNotFound
    } else if fileNotReadable {
        throw ErrorsToThrow.fileNotReadable
    } else if fileSizeIsTooHigh {
        throw ErrorsToThrow.fileSizeIsTooHigh
    }
    
    return “Data from file”
}

当一个错误被函数抛出之后,程序必须能够对这些错误做出正确的响应和处理。例如,准确定位错误原因并使用第二方案或者提示用户相关错误信息。

那些可能抛出异常或者错误的函数在调用是最好是在 do-catch 代码块使用 try 方法。其中 catch 只会在错误发生时才会被用于捕获错误或者异常行为并作为响应。

do {
    let dataFromString = try? readFiles(path: “path for file”)
} catch ErrorsToThrow.fileNotFound {
    print(“fileNotFound”)
} catch ErrorsToThrow.fileNotReadable {
    print(“fileNotReadable”)
} catch ErrorsToThrow.fileSizeIsTooHigh {
    print(“fileSizeIsTooHigh”)
}

在 Swift 中对可能抛出的错误有四种处理方法:

  • 继续向上抛出异常或错误。

  • 使用 do-catch 代码块。

  • 使用 try? 将返回值作为可选值处理。

  • 使用 try! 忽略错误直接强解包。

return 语句类似,当函数抛出错误或异常时,程序的工作流会发生改变。所以使用 try、try?、try! 等关键词进行语法区分对于后面代码中的异常定位查找是非常有用的。需要注意的是:try、try?、try! 三个关键词的使用位置是有区别的。其中 try 只能在 do-catch 代码块中使用,而后两个没有这一限制。

标签: Swift, 原创, Error