swift之异常处理流程
错误的表示
抛出错误
错误的处理
指定清理操作
错误的表示
在 Swift 中,错误用符合Error协议的类型的值来表示。这个空协议表明该类型可以用于错误处理。
wift 的枚举类型尤为适合构建一组相关的错误状态,枚举的关联值还可以提供错误状态的额外信息。例如,
你可以这样表示在一个游戏中操作自动贩卖机时可能会出现的错误状态:
enum VendingMachineError: Error {
case invalidSelection //选择无效
case insufficientFunds(coinsNeeded: Int) //金额不足
case outOfStock //缺货
}
enum OperationError : Error {
case ErrorOne
case ErrorTwo
case ErrorThree(String)
case ErrorOther
}
异常的抛出
- 这里定义了一个异常值的枚举,接下来我们再写个函数来使用这些异常值,能够抛出异常的函数一定要在
函数的表达式后面添加关键字 throws (这种函数一般称作throwing函数),如果这个函数有返回值 throws
关键字要写在 ->ReturnType前面,
func canThrowErrors() throws -> String{
//代码,有可能抛出异常的代码
}
func cannotThrowErrors() -> String{
//代码,有可能抛出异常的代码
}
func numberTest(num:Int) throws{
if num == 1 {
print("成功")
}else if num == 2 {
throw OperationError.ErrorTwo//异常抛出
}else if num == 3{
throw OperationError.ErrorThree("失败")//异常抛出
}else {
throw OperationError.ErrorOther
}
}
异常的处理(四种的方式)
异常的向上传递
init(name: String, vendingMachine: VendingMachine) throws {
try vendingMachine.vend(itemNamed: name)//这个函数抛出异常,然后传递给init函数处理
}
异常用do-cath处理
可以使用一个do-catch语句运行一段闭包代码来处理错误。如果在do子句中的代码抛出了一个错误,这个
错误会与catch子句做匹配,从而决定哪条子句能处理它
do { try expression statements } catch pattern 1 { statements } catch pattern 2 where condition { statements }
将异常转换成可选值
- 可以使用try?通过将错误转换成一个可选值来处理错误。如果在评估try?表达式时一个错误被抛出,那么表达式的值就是nil
func someThrowingFunction() throws -> Int {
// 包含异常处理
}
let x = try? someThrowingFunction()//如果有异常的话,那么x等于nil
禁止异常传递
有时你知道某个throw函数实际上在运行时是不会抛出错误的,在这种情况下,你可以在表达式前面写
try!来禁用错误传递,这会把调用包装在一个不会有错误抛出的运行时断言中。如果真的抛出了错误,你会
得到一个运行时错误。
let photo = try! loadImage(atPath: "./Resources/John Appleseed.jpg")//有错误抛出的情况,但是知道一定不会抛出异常。
指定清理操作(内存的释放)
在即将离开当前代码块时触发执行 defer 语句,不管以何种方式离开,如break,return,还是异常抛出。
defer语句内不能包含一些跳转语句。
- 在文件打开的时候牵扯到内存问题会使用defer。
func processFile(filename: String) throws {
if exists(filename) {
let file = open(filename)
defer {
close(file)
}
while let line = try file.readline() {
// 没有异常的话在这里处理文件,
}
// close(file) 会在这里被调用,即作用域的最后。
}
}