首先要明白抛出异常后异常的运动:异常被抛出后,中断整个处理,异常不断向外层(范围)传递,直到遇到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. 创建es索引-格式化和非格式化

    创建es索引-格式化和非格式化 学习了:https://www.imooc.com/video/15768 索引有结构化和非结构化的区分: 1, 先创建索引,然后POST修改mapping 首先创建索 ...

  2. 转: NetBean远程开发的格式与过程

    1. 介绍远程3种模式 https://netbeans.org/kb/docs/cnd/remote-modes.html 评注:英文的,3种模式讲的非常到位.服务器开发还是全远程比较不错.

  3. PAT 1003 Sharing (25)

    题目描写叙述 To store English words, one method is to use linked lists and store a word letter by letter. ...

  4. HDU 2009 整除的尾数 题解

    Problem Description 一个整数,仅仅知道前几位,不知道末二位.被还有一个整数除尽了.那么该数的末二位该是什么呢?   Input 输入数据有若干组,每组数据包括二个整数a,b(0&l ...

  5. SQL数据分组后取最大值或者取前几个值(依照某一列排序)

    今日做项目的时候,项目中遇到须要将数据分组后,分组中的最大值,想了想,不知道怎么做.于是网上查了查,最终找到了思路,经过比較这个查询时眼下用时最快的,事实上还有别的方法,可是我认为我们仅仅掌握最快的方 ...

  6. Android设置系统开机自己主动永不休眠

    android4.2系统增永不休眠同一时候隐藏休眠选项 1. android\frameworks\base\packages\SettingsProvider\res\values\defaults ...

  7. CSS属性中Display与Visibility的不同

    大多数人很容易将CSS属性display和visibility混淆,它们看似没有什么不同,其实它们的差别却是很大的.visibility属性用来确定元素是显示还是隐藏,这用visibility=&qu ...

  8. Neutron配置Floating IP

    下图是由一个虚拟机vm1,一个路由器ext-router,两个网络ext-net及demo-net组成的拓扑结构.要达到的目的很简单,即vm1不仅能使用私网IP和内部的其它虚拟机进行通信,还可以通过e ...

  9. 转移iOS App常见问题和回答

    打算转移公司的app,做下转移的记录 怎样转移app官方的一个视频:http://v.youku.com/v_show/id_XNjI0MjQxMzI0.html 以下是apple官方转移常见问题回答 ...

  10. 远程连接mysql速度慢的解决方法:skip-name-resolve取消DNS的反向解析

    PHP远程连接MYSQL速度慢,有时远程连接到MYSQL用时4-20秒不等,本地连接MYSQL正常,出现这种问题的主要原因是,默认安装的 MYSQL开启了DNS的反向解析,在MY.INI(WINDOW ...