zoukankan      html  css  js  c++  java
  • 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 就这样产生了。
    • 下面我们看看如何用 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 里的代码,这样就保证了不管发生什么,最后都会将文件关闭。
  • 相关阅读:
    关闭Windows的CTRL+ALT+DEL 和 ALT+TAB组合键的方法
    VC中常用文件操作(一)
    VC 创建NT服务程序
    几个操作文件的API函数
    VC中常用文件操作(二) ——INI文件操作
    初学OpenCV之图像坐标读取函数cvGet2D()
    OpenCV学习之图像读取与显示
    SLT容器之vector简单实现C++运行时多态
    C/C++文件——数据写入、读取
    OpenCV学习之视频读取与帧的提取、显示及保存
  • 原文地址:https://www.cnblogs.com/QianChia/p/8673351.html
Copyright © 2011-2022 走看看