概述
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 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时,应该要特别注意这一点