Swift 中的 Defer 是什么?
在本教程中,您将了解 defer 关键字的含义以及如何在 Swift 中使用它。您将了解在哪些情况下可以使用 defer 关键字。
什么是 defer?
defer 语句用于在将程序控制权转移到语句所在作用域之外之前执行代码。
在 Swift 中,defer 语句并非经常使用。当您希望在资源超出作用域之前清理它们时,它会很有用。defer 关键字是在 Swift 2.0 版本中引入的。
语法
// 退出作用域前要执行的初始任务
defer {
// 在此执行清理操作
// 其他语句
}
// 进一步的代码
示例
var languages = ["Swift", "Objective-C", "Kotlin", "JavaScript", "Java"] func removeLastValue() -> String? { let lastValue = languages.last defer { languages.removeLast() } return lastValue } let lastValue = removeLastValue() print("last value: \(lastValue ?? "")") print("Array: \(languages)")
输出
last value: Optional("Java")
Array: ["Swift", "Objective-C", "Kotlin", "JavaScript"]
解释
您可以查看输出,并发现上例中 languages.removeLast() 写在 return 语句之前。函数执行完成后,将执行 defer 语句并删除最后一个元素。
多个 defer
如果同一作用域中出现多个 defer 语句,则它们出现的顺序与执行顺序相反。最后定义的语句最先执行。最近被 defer 的语句将首先运行——这实际上相当于展开堆栈。
示例
func testingMultipleDefer() { defer { print("one") } defer { print("two") } defer { print("three") } print("end of function") } testingMultipleDefer()
输出
end of function three two one
Defer 不捕获值
Defer 语句不捕获变量的引用或当前值。
示例
func captureTest() { var fullName = "Mohit Chouhan" defer { print(fullName) } fullName = "Mohit Sharma" print(fullName) } captureTest()
输出
Mohit Sharma Mohit Sharma
注意 − 我们不能中断 defer 的执行,也不能在 defer 块内使用 return、continue 或 break。
一个实际的例子
func writeLog() { let file = openFile() defer { closeFile(file) } print("writing all the logs here...") } func openFile() -> String { return "defer_statement.txt" } func closeFile(_ fileName: String) { print("closing file: \(fileName)") } writeLog()
输出
writing all the logs here... closing file: defer_statement.txt
即使您对打开的文件进行了修改,如果您在函数末尾或中间 return 或 exit 此函数,defer 块也会确保文件被关闭。
关于 defer 的要点
defer 不应该尝试退出当前作用域,因为"return"就是为此而生的。
在离开当前作用域之前,请在 defer 块中执行一些任务(例如清理资源)。
实际上,无论执行如何离开当前作用域,它都保证会被执行。
defer 语句仅在执行离开当前作用域时执行,而不是在遇到 defer 语句时执行。
结论
Swift 的 defer 语句在某些情况下对于清理资源非常有用。即使团队成员更新了方法或添加了条件语句,defer 语句也能让您的 iOS 应用程序代码保持平稳运行。无论我们如何退出,defer 都会执行,并且可以防止未来项目发生可能改变范围流程的更改,从而减少发生错误的可能性。