我们在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 ) throws -> Void {
if name.isEmpty {
throw MyErrors.NO_NAME
}
if objects.count < index {
throw MyErrors.OUT_OF_RANGE
}
for object in objects {
if !(object is Int) {
throw 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", objects:objs, 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", objects:objs, index: 1)
let objs:[NSObject] = ["Ryoma" as NSObject,4 as NSObject]
try? testMyErrors(name: "Ryoma", objects:objs, index: 1)
关于异常处理还有一个点就是defer,我个人感觉他就像是Java中的finally,就是不管这个处理中有没有异常发生,都要执行的,我们可以这里面做一些自己需要的处理,而且如果我们在一个处理中写有多个defer的话,他是按照先进后出的原则执行的
func say(){
do {
let objs:[NSObject] = ["Ryoma" as NSObject,4 as NSObject]
try testMyErrors(name: "Ryoma", objects:objs, 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