概述

Swift 是一门以安全、高效和简洁为首要设计目标的编程言语,具有强大的函数式编程才能和现代化的言语特性。其中,defer 句子是 Swift 程序员常用的一种代码块,能够帮助开发者更好地控制程序的履行流程和资源管理。本文将深入剖析 Swift 中的defer句子,介绍其运用场景、运行机制和留意事项,并通过实例代码演示具体的应用

界说

A defer statement is used for executing code just before transferring program control outside of the scope that the defer statement appears in

Swift 编程言语中的一个关键字,用于界说在函数退出之前有必要履行的代码块,即当时作用域结束时调用。无论函数是正常履行结束仍是产生异常而提早退出,defer 界说的代码块都会被履行且仅会被履行一次

运用场景

This means that a defer statement can be used, for example, to perform manual resource management such as closing file descriptors, and to perform actions that need to happen even if an error is thrown.

  • 在函数内部翻开文件、网络衔接或数据库衔接等资源时,运用 defer 关键字来确保在函数履行结束后及时封闭这些资源
  • 在函数履行期间进行状况改变,如修改全局变量等操作时,运用 defer 来确保状况能够得到及时恢复
  • 在函数履行期间进行一些整理操作,如删去临时文件、开释内存等

典型用法

文件读写操作

func processFile(filename: String) throws {
    let file = File.open(filename)
    defer {
        file.close()
    }
    // 履行一些操作
}

线程安全处理

class class UnfairLock {
    private let unfairLock: os_unfair_lock_t
    init() {
        unfairLock = .allocate(capacity: 1)
        unfairLock.initialize(to: os_unfair_lock())
    }
    deinit {
        unfairLock.deinitialize(count: 1)
        unfairLock.deallocate()
    }
    func around<T>(_ closure: () throws -> T) rethrows -> T {
        os_unfair_lock_lock(unfairLock); 
        defer { os_unfair_lock_unlock(unfairLock) }
        return try closure()
    }
    func around(_ closure: () throws -> Void) rethrows {
        os_unfair_lock_lock(unfairLock);  
        defer { os_unfair_lock_unlock(unfairLock) }
        try closure()
    }
}

os_unfair_lock_lock 函数用来获取锁以确保在多线程环境下对共享资源的互斥访问,而 os_unfair_lock_unlock 函数则是开释锁。整个 around 函数的完成运用了 Swift 中的 defer 关键字,表示无论 closure 函数履行成功或失利,os_unfair_lock_unlock 函数都会被履行,确保锁的正常开释,避免了资源被长期占有的危险

留意细节

  • defer句子中的代码块不能包括任何回来句子,因为defer块并不会影响函数的回来值
  • defer 句子的履行次序与其界说次序相反,因此如果有多个defer句子存在,应该按照从后往前的次序来界说它们
  • 不可单纯地以为defer只是在函数退出的时候调用,其实是当时 scope 退出的时候调用。因此在if,guard, for, try这些句子中运用defer时,应该要特别留意这一点

参考文献

onevcat.com/2018/11/def…

github.com/Alamofire/A…