Swift Defer 延迟调用
1、Defer
在一些语言中,有
try/finally这样的控制语句,比如 Java。这种语句可以让我们在finally代码块中执行必须要执行的代码,不管之前怎样的兴风作浪。在 Swift 2.0 中,Apple 提供了defer关键字,让我们可以实现同样的效果。func checkSomething() { print("CheckPoint 1") doSomething() print("CheckPoint 4") } func doSomething() { print("CheckPoint 2") defer {
print("Clean up here")
} print("CheckPoint 3")
} // CheckPoint 1, CheckPoint 2, CheckPoint 3, Clean up here, CheckPoint 4
checkSomething()
- 上述示例可以看到,在打印出
CheckPoint 2之后并没有打印出Clean up here,而是CheckPoint 3,这就是defer的作用,它对进行了print("Clean up here")延迟。
- 上述示例可以看到,在打印出
在你的代码块就要结束前。如果你使用了
defer。在其之中的代码就会运行。等于说,给了你最后的机会来进行一些处理。如果你熟悉 BDD 或者 TDD,那么你可以参考他们中的aferAll机制。func myFunction() throws { defer { // No matter what happened I need do something
print("All done, clean up here")
} guard let item = item else { // need throws the error out
throw MyError.notExist
} guard item.count > maxNumber else { // need throws the error out
throw MyError.outOfRange
} // do something with item
// ...
}
如果你有多个
defer语句,他们在执行的顺序会和栈一样,最后一个进,第一个出。
2、Defer 示例
我们再来看一个 I/O 的示例
func writeSomething() { let file = OpenFile() let ioStatus = fetchIOStatus() guard ioStatus != "error" else {
return
} file.write() closeFile(file)
}
- 上述示例是一个 I/O 操作的伪代码,如果获取到的
ioStatus正常,那么该方法没有问题,如果ioStatus取到的是error,那么会被guard语句抓到执行return操作,这样的话closeFile(file)就永远都不会执行了,一个严重的 Bug 就这样产生了。
- 上述示例是一个 I/O 操作的伪代码,如果获取到的
下面我们看看如何用
defer来解决这个问题。func writeSomething() { let file = OpenFile() defer {
closeFile(file)
} let ioStatus = fetchIOStatus() guard ioStatus != "error" else {
return
} file.write()
}
- 我们将
closeFile(file)放在defer代码块里,这样即使ioStatus为error,在执行return前会先执行defer里的代码,这样就保证了不管发生什么,最后都会将文件关闭。
- 我们将
Swift Defer 延迟调用的更多相关文章
- defer 延迟调用
1. 延迟调用 defer 的用法很简单,只要在后面跟一个函数的调用,就能实现将这个 xxx 函数的调用延迟到当前函数执行完后再执行. defer xxx() 这是一个很简单的例子,可以很快帮助 ...
- go语言基础之defer延迟调用
1.defer作用 关键字 defer ⽤于延迟一个函数或者方法(或者当前所创建的匿名函数)的执行.注意,defer语句只能出现在函数或方法的内部. 运行场景: defer语句经常被用于处理成对的操作 ...
- ReactiveSwift源码解析(十一) Atomic的代码实现以及其中的Defer延迟、Posix互斥锁、递归锁
本篇博客我们来聊一下ReactiveSwift中的原子性操作,在此内容上我们简单的聊一下Posix互斥锁以及递归锁的概念以及使用场景.然后再聊一下Atomic的代码实现.Atomic主要负责多线程下的 ...
- Twisted 延迟调用
延迟(defer)是twisted框架中实现异步的编程体系,使程序设计可以采用事件驱动的机制 1.基本使用 defer可以看作一个管理回调函数的对象,可以向该对象添加需要的回调函数同时也可以指定该组函 ...
- 17_defer(延迟调用)关键字的使用
1.defer是延迟调用关键字,只能在函数内部使用 2.总是在main函数结束前调用(和init用法相对) 3.如果有多个defer 遵循先进后出的原则 4.和匿名函数同时使用时,如果匿名函数带有参数 ...
- go 学习笔记之解读什么是defer延迟函数
Go 语言中有个 defer 关键字,常用于实现延迟函数来保证关键代码的最终执行,常言道: "未雨绸缪方可有备无患". 延迟函数就是这么一种机制,无论程序是正常返回还是异常报错,只 ...
- Go语言系列开发之延迟调用和作用域
Hello,各位小伙伴大家好,我是小栈君,最近一段时间我们将继续分享关于go语言基础系列,当然后期小栈君已经在筹划关于java.Python,数据分析.人工智能和大数据等相关系列文章.希望能和大家一起 ...
- go 学习笔记之咬文嚼字带你弄清楚 defer 延迟函数
温故知新不忘延迟基础 A "defer" statement invokes a function whose execution is deferred to the momen ...
- 【Unity3D】Invoke,InvokeRepeating ,Coroutine 延迟调用,周期性调用
Invoke和InvokeRepeating方法,可以实现延迟调用,和周期调用 第一个是执行一次,第二个是重复执行 void Invoke(string methodName, float time) ...
随机推荐
- 解决Delphi7的自带的UTF-8编码转换函数BUG
Delphi7及其以下版本的 VCL 只支持 Ansi, 所以... WideString 与 UTF8String (定义与 AnsiString 相同) 并没有办法正确的在 VCL 中显示 Del ...
- gulp给文件加版本号
版本号用文件MD5生成 默认根据文件MD5生成,因此文件未发生改变,此版本号将不会变 所以当没有改变文件的时候,我们就不能用gulp来改变版本号了 需要安装的插件 npm install --save ...
- Linux命令02--系统管理
<1>查看当前日历:cal <2>显示或者设置时间 设置时间格式(需要管理员权限):一般都是有ntp服务的,你的系统会根据这个对照互联网时间 <3>查看进程信息:p ...
- 4.Django|ORM模型层
ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的 ...
- Python 导入requests报错No module named requests
刚开始是在Pycharm里面,发现就是不对,导入老提示No module named requests这个错误.后面发现是指向的python.exe路径不对,到setting里面设置换一下路径就好.
- 谷歌浏览器升级引起的BUG
问题描述:在谷歌浏览器中,电脑打开A系统,添加附件时无法弹框. 预期结果:添加附件,可以打开弹框. 问题分析:谷歌浏览器自动升级,自55.0.2883.75后发布的新版本均自动停用Flash插件. 解 ...
- CF 633 F. The Chocolate Spree 树形dp
题目链接 CF 633 F. The Chocolate Spree 题解 维护子数答案 子数直径 子数最远点 单子数最长直径 (最长的 最远点+一条链) 讨论转移 代码 #include<ve ...
- luogu P2657 [SCOI2009]windy数 数位dp 记忆化搜索
题目链接 luogu P2657 [SCOI2009]windy数 题解 我有了一种所有数位dp都能用记忆话搜索水的错觉 代码 #include<cstdio> #include<a ...
- BZOJ.2229.[ZJOI2011]最小割(最小割树)
题目链接 题意:给定一张无向图,求任意两点之间的最小割. 在所有点中任选两个点作为源点\(S\).汇点\(T\),求它们之间的最小割\(ans\),并把原图分成两个点集\(S',T'\),用\(ans ...
- 洛谷.1782.旅行商的背包(背包DP 单调队列)
题目链接(卡常背包) 朴素的多重背包是: \(f[i][j] = \max\{ f[i-1][j-k*v[i]]+k*w[i] \}\),复杂度 \(O(nV*\sum num_i)\) 可以发现求\ ...