defer
:用来定义以任何方式(抛错误、return等)离开代码块前必须要执行的代码,这块代码将延迟至当前作用域结束之前执行。
基本使用
func test() {
print("run test 1")
defer {
print("run defer")
}
print("run test 2")
}
// run test 1
// run test 2
// run defer
注意点
-
一个函数中可以有多个
defer
,同一作用域的defer
都是以栈的形式添加的,是以先进后出的顺序执行 -
defer
可以被阻拦添加(例如添加新defer
前就 return 了) -
defer
可以嵌套- 如果其中一层作用域的
defer
里面有多个子defer
,那么这一层作用域结束之前,同样也是以先进后出的顺序去执行里面的子defer
。
- 如果其中一层作用域的
var isAdd = true
func test() {
print("run test 1")
defer {
print("run defer 5")
}
// defer可以嵌套
defer {
// 执行这一层作用域时同样也是以先进后出的顺序去执行里面的子defer
defer {
print("run defer 4")
}
defer {
print("run defer 3")
}
print("run defer 2")
}
// defer可以被阻拦添加
guard isAdd else { return }
defer {
print("run defer 1")
}
print("run test 2")
}
// isAdd == true
// run test 1
// run test 2
// run defer 1
// run defer 2
// run defer 3
// run defer 4
// run defer 5
// isAdd == false
// run test 1
// run defer 2
// run defer 3
// run defer 4
// run defer 5
-
defer
除了可以访问当前作用域的任意变量,也可以访问所有外层作用域中的任意变量(最外层则是函数体)- 这些变量并不是copy过来的,而是有引用关系的,是真的把变量传过来的;
- 而所有内层作用域中的变量都无法访问。
func test() {
defer {
defer {
defer {
defer {
let e = 5
d += 1
c += 1
b += 1
a += 1
// 可以访问当前和所有外层作用域的任意变量
print("a: \(a),", "b: \(b),", "c: \(c),", "d: \(d),", "e: \(e)")
}
var d = 4
c += 1
b += 1
a += 1
}
var c = 3
b += 1
a += 1
}
var b = 2
a += 1
}
var a = 1
// 无法访问内层作用域的变量
// b += 1
}
// a: 5, b: 5, c: 5, d: 5, e: 5
网友评论