在swift3.0之后闭包默认都是非逃逸的。当一个闭包作为参数被传入保存后,等待稍后在调用,这样的闭包就是逃逸的,逃逸闭包必须添加@escaping标注。
看下面例子:
class ExampleClass {
var handlers:[()->Void] = []
func someEscapingFunc(closure:@escaping ()->Void) {
handlers.append(closure)
}
}
someEscapingFunc方法传入一个闭包,这个闭包没有立即执行而是被handlers保存了,这种就是闭包就是逃逸的,必须加
@escaping标注。
在逃逸闭包中使用不当容易造成内存泄漏。
class ViewController: UIViewController {
var x = 0
let example = ExampleClass()
override func viewDidLoad() {
super.viewDidLoad()
example.someEscapingFunc{[weak self] in
self?.x = 10
}
}
}
我必须这样调用才能避免造成内存泄漏。
逃逸闭包self不能隐试引用,但是在逃逸闭包中self可以隐试引用。举个例子
class ExampleClass {
var handlers:[()->Void] = []
func someEscapingFunc(closure:()->Void) {
closure()
}
}
class ViewController: UIViewController {
var x = 0
let example = ExampleClass()
override func viewDidLoad() {
super.viewDidLoad()
example.someEscapingFunc {
x = 10
}
}
}
像上面那样调用,不用谢self。而且非逃逸闭包不会造成内存泄漏。