Swift 异常处理
Posted iLife~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift 异常处理相关的知识,希望对你有一定的参考价值。
Swift 异常处理
错误类型
- 语法错误
- 逻辑错误
- 运行时错误
自定义错误
通过error 协议来自定义错误,通常我们使用枚举类型来定义错误
enum SomeError :Error {
//关联类型是符串
case illegalArg(String)
case outOfBounds(Int,Int)
case outOfMemory
}
调用可能会抛出异常的函数的时候需要使用try关键字,do...catch 来捕捉错误,如果不处理,Error 将抛给上层函数,到了顶层系统也没处理,则系统会闪退处理
//如果方法要抛出异常,则需要throw关键字
func divide(_ num:Int,_ num2:Int)throws -> Int {
if 0 == num2 {
throw SomeError.illegalArg("除数不能为0")
}
return num/num2
}
Fatal error: Error raised at top level: Swift_Study.SomeError.illegalArg("除数不能为0"): file Swift/ErrorType.swift, line 200
2021-05-11 16:02:10.028783+0800 Swift_Study[60673:713389] Fatal error: Error raised at top level: Swift_Study.SomeError.illegalArg("除数不能为0"): file Swift/ErrorType.swift, line 200
(lldb)
捕捉异常处理
do{
print(try divide(10,2))
}catch let SomeError.illegalArg(msg){
print("参数异常",msg)
}catch let SomeError.outOfBounds(size, index){
print("下标越界:","size = \\(size)","index = \\(index)")
}catch SomeError.outOfMemory{
print("内存溢出")
}catch{
print("其他错误")
}
在此,我们定义了另一种error类型
enum MyError :Error {
//关联类型是字符串
case illegalArg(String)
case outOfBounds(Int,Int)
case outOfMemory
}
抛出这种类型的异常,然后用SomeError类型去接收和捕捉处理会怎么样
func divide(_ num:Int,_ num2:Int)throws -> Int {
if 0 == num2 {
throw MyError.illegalArg("除数不能为0")
}
return num/num2
}
//转换异常为SomeError类型,然后处理
do{
print(try divide(10,0))
}catch let error as SomeError{
print(error)
}
//只要是SomeError,就捕捉处理
do{
print(try divide(10, 0))
}catch is SomeError{
print(SomeError.illegalArg("cuowu"))
}
结果是,并不能捕捉到异常,系统会闪退处理
Fatal error: Error raised at top level: Swift_Study.MyError.illegalArg("除数不能为0"): file Swift/ErrorType.swift, line 200
2021-05-11 16:23:57.553676+0800 Swift_Study[61457:730733] Fatal error: Error raised at top level: Swift_Study.MyError.illegalArg("除数不能为0"): file Swift/ErrorType.swift, line 200
(lldb)
如果抛出的还是SomeError
类型的错误,怎转换是没有问题的
illegalArg("除数不能为0")
illegalArg("cuowu")
Program ended with exit code: 0
try? try!
如果只是想调用下这个抛出异常的函数,不想去处理错误,也就是不想用do...catch来捕捉,怎么可以?->用try? try! 来调用
如果调用成功,函数的返回结果会被包装成可选类型
如果函数抛出了错误,怎返回值为nil
//a b 效果是等价的var a = try? divide(20, 0)var b :Int?do{ b = try divide(20, 0)}catch{ b = nil }
rethrows
Rethorws 表明,函数本身不会抛出错误,但是闭包参数可能会抛出错误,那么它会将错误向上抛。
比如
func exec (_ fn:(Int,Int) throws ->Int,num1:Int ,num2:Int) rethrows{ print(try fn(num1,num2))}
这个函数有三个参数,第一个参数是一个可能抛出异常的函数fn,也可能是个闭包表达式,这个函数本身不会抛出异常,但是他的参数可能会抛出异常,所以
此处用rethrows
defer
用来定义以 任何方式 退出代码块前,必须要执行的代码。
不管是正常方式,还是异常退出,还是return,
func run() -> Void { defer { print("退出前一定会执行1") } defer { print("退出前一定会执行2") } print("xxxxx")}
xxxxx退出前一定会执行2退出前一定会执行1
注意:defer 的定义顺序与执行顺序相反
以上是关于Swift 异常处理的主要内容,如果未能解决你的问题,请参考以下文章