Swift1.2发布时就已经有这个关键字了。正确使用它可以使我们避免许多不希望的保留环。
@noescape主要用在对函数中的closure参数修饰。
使用@noescape修饰closure后,clousure的生命周期要比函数的调用周期短,也就是说clousure不能随意在函数外调用。
@noescape使用注意点:
- 别修饰的clousure不能用于asynchronously(异步)
class A1 {
func async(@noescape code:() -> ()) -> Void {
/*报错:error: invalid conversion from non-escaping function of type '@noescape () -> ()' to potentially escaping function type 'dispatch_block_t' (aka '@convention(block) () -> ()')*/
dispatch_async(dispatch_get_main_queue(), code);
}
}
class A2 {
func async(@noescape code:() -> ()) -> Void {
dispatch_async(dispatch_get_main_queue(), code);
}
}
- 不能进行存储赋给另一个closure变量
class A1 {
func async(@noescape code:() -> ()) -> Void {
let codeConst:()->() = code;
codeConst()
}
}
class A2 {
func async(code:() -> ()) -> Void {
let codeConst:()->() = code;
codeConst()
}
}
- 不能在另一个非@noescape closure中进行捕获
class A9 {
func capture(@noescape code: ()->()) -> Void {
let captured = {
code()
}
captured()
}
}
class A10 {
func capture(code: ()->()) -> Void {
let captured = {
code()
}
captured()
}
}
- 在对所属class或者strutt的其他属性或函数进行操作时无需加
self.
class A4{
var b: (Void -> Void)!
var k = 0//用来调用的
func aa(@noescape a: (Void->Void)){
a()
}
func bb(){
aa {
() -> Void in
k = 1//一般的closure都是要self.k = 1,@noescape则不需要
}
}
总结
@noescape限制了closure的使用范围,当你确定该closure不会在函数外调用时,则最好加上@noescape修饰符,这样可以带来一些性能的提升。同时在引用属性或其他方法时无需加self.,也避免了循环引用的问题。
