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 就这样产生了。
  • 下面我们看看如何用 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 里的代码,这样就保证了不管发生什么,最后都会将文件关闭。

Swift Defer 延迟调用的更多相关文章

  1. defer 延迟调用

    1. 延迟调用 defer 的用法很简单,只要在后面跟一个函数的调用,就能实现将这个  xxx 函数的调用延迟到当前函数执行完后再执行. defer xxx()   这是一个很简单的例子,可以很快帮助 ...

  2. go语言基础之defer延迟调用

    1.defer作用 关键字 defer ⽤于延迟一个函数或者方法(或者当前所创建的匿名函数)的执行.注意,defer语句只能出现在函数或方法的内部. 运行场景: defer语句经常被用于处理成对的操作 ...

  3. ReactiveSwift源码解析(十一) Atomic的代码实现以及其中的Defer延迟、Posix互斥锁、递归锁

    本篇博客我们来聊一下ReactiveSwift中的原子性操作,在此内容上我们简单的聊一下Posix互斥锁以及递归锁的概念以及使用场景.然后再聊一下Atomic的代码实现.Atomic主要负责多线程下的 ...

  4. Twisted 延迟调用

    延迟(defer)是twisted框架中实现异步的编程体系,使程序设计可以采用事件驱动的机制 1.基本使用 defer可以看作一个管理回调函数的对象,可以向该对象添加需要的回调函数同时也可以指定该组函 ...

  5. 17_defer(延迟调用)关键字的使用

    1.defer是延迟调用关键字,只能在函数内部使用 2.总是在main函数结束前调用(和init用法相对) 3.如果有多个defer 遵循先进后出的原则 4.和匿名函数同时使用时,如果匿名函数带有参数 ...

  6. go 学习笔记之解读什么是defer延迟函数

    Go 语言中有个 defer 关键字,常用于实现延迟函数来保证关键代码的最终执行,常言道: "未雨绸缪方可有备无患". 延迟函数就是这么一种机制,无论程序是正常返回还是异常报错,只 ...

  7. Go语言系列开发之延迟调用和作用域

    Hello,各位小伙伴大家好,我是小栈君,最近一段时间我们将继续分享关于go语言基础系列,当然后期小栈君已经在筹划关于java.Python,数据分析.人工智能和大数据等相关系列文章.希望能和大家一起 ...

  8. go 学习笔记之咬文嚼字带你弄清楚 defer 延迟函数

    温故知新不忘延迟基础 A "defer" statement invokes a function whose execution is deferred to the momen ...

  9. 【Unity3D】Invoke,InvokeRepeating ,Coroutine 延迟调用,周期性调用

    Invoke和InvokeRepeating方法,可以实现延迟调用,和周期调用 第一个是执行一次,第二个是重复执行 void Invoke(string methodName, float time) ...

随机推荐

  1. 解决Delphi7的自带的UTF-8编码转换函数BUG

    Delphi7及其以下版本的 VCL 只支持 Ansi, 所以... WideString 与 UTF8String (定义与 AnsiString 相同) 并没有办法正确的在 VCL 中显示 Del ...

  2. gulp给文件加版本号

    版本号用文件MD5生成 默认根据文件MD5生成,因此文件未发生改变,此版本号将不会变 所以当没有改变文件的时候,我们就不能用gulp来改变版本号了 需要安装的插件 npm install --save ...

  3. Linux命令02--系统管理

    <1>查看当前日历:cal <2>显示或者设置时间 设置时间格式(需要管理员权限):一般都是有ntp服务的,你的系统会根据这个对照互联网时间 <3>查看进程信息:p ...

  4. 4.Django|ORM模型层

    ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的 ...

  5. Python 导入requests报错No module named requests

    刚开始是在Pycharm里面,发现就是不对,导入老提示No module named requests这个错误.后面发现是指向的python.exe路径不对,到setting里面设置换一下路径就好.

  6. 谷歌浏览器升级引起的BUG

    问题描述:在谷歌浏览器中,电脑打开A系统,添加附件时无法弹框. 预期结果:添加附件,可以打开弹框. 问题分析:谷歌浏览器自动升级,自55.0.2883.75后发布的新版本均自动停用Flash插件. 解 ...

  7. CF 633 F. The Chocolate Spree 树形dp

    题目链接 CF 633 F. The Chocolate Spree 题解 维护子数答案 子数直径 子数最远点 单子数最长直径 (最长的 最远点+一条链) 讨论转移 代码 #include<ve ...

  8. luogu P2657 [SCOI2009]windy数 数位dp 记忆化搜索

    题目链接 luogu P2657 [SCOI2009]windy数 题解 我有了一种所有数位dp都能用记忆话搜索水的错觉 代码 #include<cstdio> #include<a ...

  9. BZOJ.2229.[ZJOI2011]最小割(最小割树)

    题目链接 题意:给定一张无向图,求任意两点之间的最小割. 在所有点中任选两个点作为源点\(S\).汇点\(T\),求它们之间的最小割\(ans\),并把原图分成两个点集\(S',T'\),用\(ans ...

  10. 洛谷.1782.旅行商的背包(背包DP 单调队列)

    题目链接(卡常背包) 朴素的多重背包是: \(f[i][j] = \max\{ f[i-1][j-k*v[i]]+k*w[i] \}\),复杂度 \(O(nV*\sum num_i)\) 可以发现求\ ...