逃逸闭包和非逃逸闭包的理解:
Swift中的闭包有两种:逃逸闭包和非逃逸闭包。逃逸闭包表示闭包将在函数返回之后执行;而非逃逸闭包则表示在函数返回前,即函数内部执行。
那么我们是否可以理解为:如果闭包作为某个函数的参数,这个函数在执行闭包时,如果为异步执行,闭包就为逃逸闭包;如果为同步执行,闭包就为非逃逸闭包。
逃逸闭包的条件:
逃逸闭包必须满足以下两个条件:
1、闭包作为一个参数传到函数中。
2、闭包在函数返回之后才执行。
需要在参数前面加入标注: @escaping,用来指明这个闭包是允许“逃逸”出这个函数的。
注意:将一个闭包标记为 @escaping 意味着你必须在闭包中显式地引用。
Swift3.0中闭包捕捉策略的改变:
在Swift2.0中,一个函数的参数的闭包捕捉策略都默认为逃逸的,如果需要表示非逃逸闭包,则需要用@noescape关键字来修饰闭包。而大多数人在写闭包参数时都容易忽略判断闭包是否逃逸,如果闭包都被当做了逃逸闭包处理,这对闭包的内存管理优化并不太友好。所以在Swift3.0中,对此进行了对调的改变:所有的闭包都默认为非逃逸闭包,弃用了@noescape。如果需要表示逃逸闭包,则使用@escaping关键字来修饰闭包。
实例:
以下代码,callBack在函数执行完后的1秒后才执行,所以是逃逸闭包。
func startRequest(callBack: ()->Void) {
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 1) {
callBack()
}
}
这样就需要显式的声明@escaping才能够编译通过