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 somethingprint("All done, clean up here")}guard let item = item else {// need throws the error outthrow MyError.notExist}guard item.count > maxNumber else {// need throws the error outthrow 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 就这样产生了。
  • 下面我们看看如何用 defer 来解决这个问题。

    func writeSomething() {let file = OpenFile()defer {closeFile(file)}let ioStatus = fetchIOStatus()guard ioStatus != "error" else {return}file.write()
    }
    • 我们将 closeFile(file) 放在 defer 代码块里,这样即使 ioStatuserror,在执行 return 前会先执行 defer 里的代码,这样就保证了不管发生什么,最后都会将文件关闭。

转载于:https://www.cnblogs.com/QianChia/p/8673351.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367518.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql strtok,strtok()和strtok_r()

下面的说明摘自于最新的Linux内核2.6.29,说明了strtok()这个函数已经不再使用,由速度更快的strsep()代替/** linux/lib/string.c** Copyright (C) 1991, 1992 Linus Torvalds*//** stupid library routines.. The optimized versions should generally b…

from 下拉框多个值提交_Git commit 多行信息提交

git commit可接受多个消息标志(-m)来允许多行提交原文地址:https://www.stefanjudis.com/today-i-learned/git-commit-accepts-several-message-flags-m-to-allow-multiline-commits/原文作者:Stephan Schneider在命令行上使用git时,您可能已…

处理缓慢的资源泄漏

使用Java监视器查找资源泄漏 查找缓慢的资源泄漏是使应用程序服务器长时间保持正常运行的关键。 在这里,我解释了如何使用Java监视器来发现缓慢的资源泄漏,以及如何验证它们是实际的泄漏,而不仅仅是额外的预分配到某些HTTP连接器或数据库池中…

jquery简单实现点击弹出层效果实例

先看效果图&#xff1a;完整例子&#xff1a; <!-- 渐变弹出层 --><div id"race"><a href"#">点击</a></div><div id"racePop" class"raceShow">这里是弹出层效果</div> <script type&q…

Openfire源码阅读(一)

本篇先分析openfire源码的主要流程&#xff0c;模块细节后续再继续分析&#xff1b; 一、简介&#xff1a; Openfire是开源的实时协作服务器&#xff08;RTC&#xff09;&#xff0c;它是基于公开协议XMPP&#xff08;RFC-3920&#xff09;&#xff0c;并在此基础上实现了XMPP-…

常见的linux命令及其翻译

常见的linux指令 1、ls ll 查看文件信息 2、cd 切换工作目录 cd 或 cd ~ 切换到/home/用户目录 cd. 切换到当前目录 cd.. 切换到上级目录 cd- 切换入上次所在的目录 3、clear 或 ctrl l 清屏 4、pwd 显示当前路径 5、mkdir 创建目录 6、rm 删除文件 rm -r 删除文件夹 7、cp 拷…

php 查询方法all,获取多条:all静态方法

查询多条数据&#xff1a;all( )方法all方法与前节课学习的get方法都是静态方法&#xff0c;可用模型类直接访问2. 源码&#xff1a;/*** 查找所有记录* access public* param mixed $data 主键列表或者查询条件(闭包)* param array|string $with 关联预查询* param b…

Google GSON入门

在Java世界中&#xff0c;JSON已成为事实上的XML数据交换格式标准&#xff0c;因为它的易用性和传输效率高。 如果您不了解JSON&#xff0c;那就是Javascript对象表示法&#xff0c;这是一种基于文本的数据交换格式&#xff0c;是名称-值的集合&#xff0c;其中名称严格是字符…

[译文]过犹不及,别再在编程中高射炮打蚊子

原文链接&#xff1a;Anyway,stop recommending bazookas to kill flies in programming. 众成翻译地址&#xff1a;过犹不及&#xff0c;别再在编程中高射炮打蚊子 译者注&#xff1a;翻译这篇吐槽的文章&#xff0c;主要是为了自省~日常工作中确实会犯类似的错误&#xff0…

Java中的for循环

上一章呢我们学习了一下java中的while循环和do while循环 现在我们来了解一下另外一种循环 for循环 for循环是编程语言中一种开界的循环语句&#xff0c;而循环语句 由循环体及循环的终止条件两部分组成&#xff0c;for循环其在各种编程语言中的实现与表达有所出入&#xff0…

SpringFox swagger2 and SpringFox swagger2 UI 接口文档生成与查看

依赖&#xff1a; <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 --> <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version> <…

matlab期末复习资料,MATLAB期末复习习题及答案

MATLAB期末复习习题及答案13&#xff0c; ysin(x)&#xff0c;x从0到2 &#xff0c; x0.02 &#xff0c;求y的最大值、最小值、均值和标准差。(应用max,min,mean,std) 14&#xff0c; 参照课件中例题的方法&#xff0c;计算表达式z 10x3 y5e xcontour, hold on, quiver)15&…

多核可扩展计数器

到处都需要计数器&#xff0c;例如&#xff0c;查找应用程序的关键KPI&#xff0c;应用程序的负载&#xff0c;服务的请求总数&#xff0c;用于查找应用程序吞吐量的一些KPI等。 由于所有这些需求&#xff0c;并发复杂性也增加了&#xff0c;这使这个问题变得有趣。 如何实现…

三年前端,面试思考(二)

为什么还有&#xff08;二&#xff09; 没有想到上一篇 《三年前端&#xff0c;面试思考》 有这么多前端同学看到。 在评论区也有很多鼓励和质疑的声音&#xff0c;而且群里面交流的同学两天就达到了700人。 群里有同学问了很多问题&#xff0c;同时希望我再分享一些面试技巧…

React入门-ReactDOM.render()介绍

React中的核心概念 1 虚拟DOM&#xff08;Virtual DOM&#xff09;2 Diff算法&#xff08;虚拟DOM的加速器&#xff0c;提升React性能的法宝&#xff09;虚拟DOM&#xff08;Vitural DOM&#xff09; React将DOM抽象为虚拟DOM&#xff0c;虚拟DOM其实就是用一个对象来描述DOM&a…

51单片机auxr寄存器_MCS-51单片机有几个工作寄存器

工作寄存器有4组&#xff0c;每组都是8个工作寄存器R0~R7&#xff0c;通过PSW中的RS1、RS0两位来选择使用哪一组&#xff0c;如果不选&#xff0c;默认是选择第0组。RS1RS0组合为00时&#xff0c;选中第0组工作寄存器&#xff0c;R0~R7地址为00H~07H;RS1RS0组合为01时&#xff…

柯里化

柯里化(currying)&#xff0c;是指把接受多个参数的函数变换成接受一个单一参数&#xff08;最初函数的第一个参数&#xff09;的函数&#xff0c;并且返回接受余下参数而且返回结果的新函数的技术。 柯里化是理解装饰器函数的一个非常重要的知识点。 比如&#xff0c;将加法函…

matlab中quat2angle,RPY_Euler_Quaternion_AngleAxis角度转化:Matlab、Python、Halc

RPY_Euler_Quaternion_AngleAxis角度转化&#xff1a;Matlab、Python、HalcRPY_Euler_Quaternion_AngleAxis角度转化&#xff1a;Matlab、Python、Halcon版本UR协作机器人和Franka机器人导出的位姿为angleVector&#xff0c;三个量表示&#xff0c;在Matlab中angleVector是四个…

基本注射/资格赛,范围

这是上周解决的DI / CDI基础知识的延续-在本文中&#xff0c;我将讨论基础注入&#xff0c;限定词和范围。 在上一个主题中&#xff0c;我们提供了有关DI / CDI概念的大量信息&#xff0c;我们还讨论了如何使用注释加载这些bean或类-这构成了对象的组成并创建了关于如何进行采…

100*100的 canvas 占多少内存?

题目 100*100的 canvas 占多少内存&#xff1f; 在 三年前端&#xff0c;面试思考 中提到了一个题目&#xff0c;非常有新意&#xff0c;这里分享一下当时面试的思考过程。 解题思路 其实真正的答案是多少我并不清楚&#xff0c;面试过程中面试官也不期待一个准确的答案&am…