首先要明白抛出异常后异常的运动:异常被抛出后,中断整个处理,异常不断向外层(范围)传递,直到遇到catch代码块群,会与catch代码块的条件进行匹配,匹配符合则进入此代码块处理。如果遇到没有条件的catch{}那么直接在这个代码里处理。如果抛出的异常一直到最外层仍没有被catch{}处理,那么程序会卡住(后面的处理全部中断)

举个简单的例子,异常和抛出异常的函数和之前博文里的是一样的

enum numTest: Int, Error  {

case _0, _1, _2, _3

case nothing = 999

}

func errorTest(by num: Int) throws -> String {

switch num {

case 0:

throw numTest._0

case 1:

throw numTest._1

case 2:

throw numTest._2

case 3:

throw numTest._3

case 10:

throw numTest.nothing

default:

return "OK" + " \(num)"

}

}

我们用这一段代码来测试

print("即将开始测试")

try errorTest(by: 0)

print("测试结束")

print("因为异常没有被捕捉,所以这两句话不会运行")

运行结果如下:

即将开始测试

换言之,如果我们抛出了异常,那就必须进行处理,不想处理?那么就加个空的无条件的catch{},为了方便观测效果,我们在catch里输出测试中

print("即将开始测试")

do {

try errorTest(by:
0)

}catch {

print("---测试中---")

}

print("测试结束")

print("因为异常被捕捉,所以这两句话会运行")

运行结果如下:

即将开始测试

---测试中---

测试结束

因为异常被捕捉,所以这两句话会运行

由以上测试可知,抛出的异常必须被处理,不然异常会导致程序中断,出现假死现象

可是,每次都要加上do-catch这一长串,无论是从代码的可读性还是写代码的角度都是非常不好的。这里,try?与try!就可以大显身手了

其实到这里,相信大家也很清楚try?和try!的作用了。

没错,try?是一个可选绑定,当后面运行的可以抛出异常的函数没有抛出异常,则直接运行。当抛出异常,则跳过此函数。既然是可选绑定,那么如果用在条件里,如果没抛出异常,那么返回的值带入声明量(void返回的是void的空值,不是nil),如果抛出,可选绑定判定为false,和普通的可选绑定一样

先看下面这个例子

print("即将开始测试")

try?
errorTest(by:
0)

print("测试结束")

运行结果如下:

即将开始测试

测试结束

把try?改成try

print("即将开始测试")

try errorTest(by:
0)

print("测试结束")

运行结果如下:

即将开始测试

 

带入条件

for i in
0 ..< 10
where i == 3 ||
i == 5 {

//for ] {

print("即将开始测试")

if let myTest =
try? errorTest(by: i)
{

print("测试中,",
terminator: "")

print("没有抛出异常,
测试值\(myTest)")

}else {

print("测试中,",
terminator: "")

print("抛出异常")

}

print("测试结束")

print("-----------")

}

运行结果如下:

即将开始测试

测试中,抛出异常

测试结束

-----------

即将开始测试

测试中,没有抛出异常,
测试值OK 5

测试结束

-----------

最后再来看看try!,这个很明显了,就是默认不会抛出异常,直接运行,如果抛出运行在编译出错

print("即将开始测试")

print("正常值:
", try!
errorTest(by:
6))

print("测试结束")

运行结果如下:

即将开始测试

正常值:  OK
6

测试结束

 

最后总结一下,try?和try!主要用在对异常抛出函数进行不需要捕捉异常的处理。当然,一般不建议用try!,后期容易出问题

Swift异常处理的try?与try!的更多相关文章

  1. Swift异常处理:throw和rethrow

    Swift异常处理体现了函数式语言的特性.因此我们能够传一个会抛出异常的函数闭包(高阶函数)作为參数传到还有一个函数中(父函数),父函数能够在子函数抛出异常时直接向上抛出异常,这时用rethrowke ...

  2. iOS - Swift 异常处理

    前言 在 Swift 1.0 时代是没有异常处理和抛出机制的,如果要处理异常,要么使用 if else 语句或 switch 语句判断处理,要么使用闭包形式的回调函数处理,再要么就使用 NSError ...

  3. Swift # 异常处理

    面向轨道编程 - Swift 中的异常处理 问题 在开发过程中,异常处理算是比较常见的问题了. 举一个比较常见的例子:用户修改注册的邮箱,大概分为以下几个步骤: 接收到一个用户的请求:我要修改邮箱地址 ...

  4. Swift异常处理

    在Swift里,抛出的异常必须继承Error这个协议.那么这个协议是什么呢? 按住command再点击Error我们可以看到, public protocol Error { } extension ...

  5. swift 中异常的处理方法

    swift 中什么时候需要处理异常,在调用系统某个方法的时,该方法最后有一个throws 说明该方法会抛出异常,如果一个方法抛出异常,那么需要对该异常进行处理 swift 异常处理提供了三种方法 方式 ...

  6. Swift try try! try?使用和区别

    Swift try try! try?使用和区别 一.异常处理try catch的使用 1. swift异常处理 历史由来 Swift1.0版本 Cocoa Touch 的 NSError ,Swif ...

  7. Swift 使用 日常笔记

    //------------------- var totalPrice: Int = { willSet(newTotalPrice) { //参数使用new+变量名且变量名首地址大写 printl ...

  8. Mac终端使用swift REPL异常处理方法

    Mac终端使用swift REPL异常处理方法 终端使用swift命令出现 warning: Swift error in module libmarisa.dylibDebug info from ...

  9. Swift 2.0 异常处理

    转自:http://www.jianshu.com/p/96a7db3fde00 WWDC 2015 宣布了新的 Swift 2.0. 这次重大更新给 Swift 提供了新的异常处理方法.这篇文章会主 ...

随机推荐

  1. C++类型的转换

    C风格转换是“万能的转换”,但需要程序员把握转换的安全性,编译器无能为力:static_cast最接近于C风格转换,但在无关类指针转换时,编译器会报错,提升了安全性:dynamic_cast要求转换类 ...

  2. vimrc 避免中文乱码配置

    et smsyntax onset ts=4set sts=4set sw=4set hlsearchset rulerset backspace=indent,eol,startset encodi ...

  3. c++面试题目(3)

    这些东西有点烦,有点无聊.如果要去C++面试就看看吧.几年前网上搜索的.刚才看到,就整理一下,里面有些被我改了,感觉之前说的不对或不完善. 1.求下面函数的返回值( 微软) int func(x)  ...

  4. plsql 无需配置客户端连接.

    plsql 无需配置客户端连接. (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.0.5)(PORT=1521)))(C ...

  5. Intel processor brand names-Xeon,Core,Pentium,Celeron----Quark

    http://en.wikipedia.org/wiki/Intel_Quark Intel Quark From Wikipedia, the free encyclopedia     Intel ...

  6. 项目Beta冲刺(团队1/7)

    项目Beta冲刺(团队1/7) 团队名称: 云打印 作业要求: 项目Beta冲刺(团队) 作业目标: 完成项目Beta版本 团队队员 队员学号 队员姓名 个人博客地址 备注 221600412 陈宇 ...

  7. C++的string连接(a = a + b 与 a += b)

    大一学习C语言的时候,书上就写着a = a + b与 a += b等价,但是提倡用后者. 在CSDN上也看到一个关于a+=b和a=a+b的区别的帖子,大概内容如下:------------------ ...

  8. 闭包传参 余额计算 钩子hook 闭包中的this JavaScript 钩子

    闭包传参  余额计算    钩子hook 小程序 a=function(e){console.log(this)}() a=function(e){console.log(this)}() VM289 ...

  9. HDU 6122 今夕何夕 【数学公式】 (2017"百度之星"程序设计大赛 - 初赛(A))

    今夕何夕 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  10. mysql 查询表死锁 和结束死锁的表步骤以及锁表等级

    1.查询是否锁表show OPEN TABLES where In_use > 0; 2.查询进程 show processlist  查询到相对应的进程===然后 kill    id 补充: ...