首先要明白抛出异常后异常的运动:异常被抛出后,中断整个处理,异常不断向外层(范围)传递,直到遇到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. 转: memcached Java客户端spymemcached的一致性Hash算法

    转自:http://colobu.com/2015/04/13/consistent-hash-algorithm-in-java-memcached-client/ memcached Java客户 ...

  2. SQL基础--&gt;层次化查询(START BY ... CONNECT BY PRIOR)

    --====================================================== --SQL基础-->层次化查询(START BY ... CONNECT BY ...

  3. Linux下mount FreeBSD分区

    假设须要从第二块硬盘复制文件.该硬盘格式化为UFS 2文件系统.怎样mount 由FreeBSD创建的UFS 2文件系统到Ubuntu系统上呢? UFS文件系统广泛的使用在不同的操作系统(比如:HP- ...

  4. @Transactional 无效的解决方案

    1 .在需要事务管理的地方加@Transactional 注解.@Transactional 注解可以被应用于接口定义和接口方法.类定义和类的 public 方法上 . 2 . @Transactio ...

  5. iOS UILabel换行同时修改字体大小颜色

    UIButton *onlyPriceBtn = [UIButton buttonWithType:UIButtonTypeCustom]; onlyPriceBtn.layer.borderColo ...

  6. java中InputStream String

    Java 中获取输入流时,有时候须要将输入流转成String,以便获取当中的内容 ,以下总结一下 InputStream 转成String 的方式  方法1: public String conver ...

  7. Scaling with Microservices and Vertical Decomposition

    Scaling with Microservices and Vertical Decomposition – dev.otto.de https://dev.otto.de/2014/07/29/s ...

  8. devm_regmap_init_i2c【转】

    本文转载自:http://blog.csdn.net/u011975319/article/details/52128845 本文有此处转载http://blog.csdn.net/luckywang ...

  9. How to create a List of ValueTuple?

    ValueTuple需要通过NuGet安装System.ValueTuple https://docs.microsoft.com/en-us/dotnet/csharp/tuples?view=ne ...

  10. JavaScript 检查 email 地址的正则表达式

    JavaScript 检查 email 地址的正则表达式​1.代码(1)<html><head><title>Checking an email address - ...