swift3新路程11错误处理Error Handling

我们在Java等其他语言之都知道有错误处理 基本上都是 try和catch配对的

那么在swift中同样也有

我们首先可以定义一下自己的错误类型如下面

enum MyErrors:Error {
    case NOT_NUMBERIC
    case NO_NAME
    case OUT_OF_RANGE
    
}
对于异常的抛出,同样是使用throw关键字,我们使用throws来标记某个函数有异常抛出

我们来定义一个函数,用来做异常抛出

func testMyErrors(name:String,objects:[NSObject],index:Int ) <span style="color:#ff0000;">throws</span> -> Void {
    if name.isEmpty {
        <span style="color:#ff0000;">throw</span> MyErrors.NO_NAME
    }
    if objects.count < index {
        <span style="color:#ff0000;">throw</span> MyErrors.OUT_OF_RANGE
    }
    for object in objects {
        if !(object is Int) {
            <span style="color:#ff0000;">throw</span> MyErrors.NOT_NUMBERIC
        }
    }
    print("Name is \(name)")
}


然后我们如何捕获异常并做处理呢?
do {
    let objs:[NSObject] = [3 as NSObject,4 as NSObject]
    try testMyErrors(name: "",objects:objs,index: 1)
} catch MyErrors.NO_NAME {
    print("名称为空")
}
我们看到使用的是 do 和 catch 当然还有try 不过try的位置跟我们所熟悉的Java代码的位置有所不同

我们这里讲name设置为空,那么就会抛出一个MyErrors.NO_NAME的异常,我们在catch中可以捕获,并做相应的处理,那么这里将会输出”名字为空“的信息

当然这是我们已经知道的可能发生的异常,我们可以精确地捕捉到,我们都知道Java中的异常处理一般是按照从小到大的范围进行网络的,最后就是最大的异常类型Exception

在swift中同样也可以,上面我们知道了名字可能为空,其他的具体还会发生什么,我们可能不太清楚,我们就可以使用下面的处理

do {
    let objs:[NSObject] = ["Ryoma" as NSObject,4 as NSObject]
    try testMyErrors(name: "Ryoma",index: 1)
} catch MyErrors.NO_NAME {
    print("名称为空")
} catch let myError as MyErrors {
    print(myError)
} catch {
    print(error)
}
这里我们看到名字不会出现问题了,但是数组内的第一项不是Int类型的,这时肯定会出异常,我们的MyErrors.NO_NAME这个类型肯定捕获不到的,但是我们在后面定一个myError是MyErrors的类型,也就是如果发生的错误是MyErrors类型的,几遍我们上面的catch没有捕获到,我们的myError也可以捕获到,并做相应的处理。

如果说在上面的业务代码块中出现了我们无法预测的错误,不在我们所能想到的错误类型中,那也不怕,我们最后的catch会帮我们捕获到,并做处理。

最后的catch中如果我们没有对Error的名字做出什么定义的话(myError就是我们自己定义的名字)话,会有一个默认的错误类型名就是error


当然除了上面的这些错误处理同样还有一种处理,我们使用 try?形式

我们还是使用上面的异常

let objs:[NSObject] = ["Ryoma" as NSObject,4 as NSObject]
try testMyErrors(name: "Ryoma",index: 1)

这样写的话因为没有catch,是无法捕获异常的,程序肯定是崩溃的
let objs:[NSObject] = ["Ryoma" as NSObject,4 as NSObject]
try? testMyErrors(name: "Ryoma",index: 1)

如果我们这样写了,使用了try?的话程序就会ok的结束,如果try?后面的执行抛出了异常,那么这个异常会被忽略,如果try?的后面是具有返回值的表达式,那么这个表达式的值就是nil,如果没有异常发生,那么这个表达式的值就会被转成一个可选的值(有可能有也有可能为nil)

关于异常处理还有一个点就是defer,我个人感觉他就像是Java中的finally,就是不管这个处理中有没有异常发生,都要执行的,我们可以这里面做一些自己需要的处理,而且如果我们在一个处理中写有多个defer的话,他是按照先进后出的原则执行的

func say(){
    do {
        let objs:[NSObject] = ["Ryoma" as NSObject,4 as NSObject]
        try testMyErrors(name: "Ryoma",index: 1)
    } catch MyErrors.NO_NAME {
        print("名称为空")
    } catch let myError as MyErrors {
        print(myError)
    } catch {
        print(error)
    }
    defer {
        print("finally will be executed even if there's an error")
    }
    defer {
        print("defer2")
    }
    defer {
        print("defer3")
    }
}
say()

输出

NOT_NUMBERIC

defer3

defer2

finally will be executed even if there's an error

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...