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 里的代码,这样就保证了不管发生什么,最后都会将文件关闭。
  • 相关阅读:
    javascript时间戳和日期字符串相互转换
    jquery两稳定版本比较~~
    原生的强大DOM选择器querySelector
    分享一个自定义的 console 类,让你不再纠结JS中的调试代码的兼容
    基于Mesos运行Spark
    chrome插件 postman 可以调用restful服务
    cassandra优秀博客集
    Cassandra监控
    Cassandra
    SecureCRT中文显示乱码的解决方法
  • 原文地址:https://www.cnblogs.com/QianChia/p/8673351.html
Copyright © 2011-2022 走看看