在使用Swift进行编程的时候我们经常使用闭包,闭包虽然好,但是不可避免地会带来“保留环”问题,考虑下面的情况:
在某个动画框架中有一个loop函数:
func loop(duration:NSTimeInterval,reverse:Bool,animations:()->Bool )
在我们自己的类中定义一个动画方法,使用了这个函数:
class MyView:UIView{
func animations(){
loop(duration:0.5,reverse:true){
self.scale(1.25)
}
}
func scale(scale:Double){...}
}
你会发现在闭包中捕获了self,loop函数循环每次都调用闭包,这样会一直保留self。而闭包中的操作其实是一成不变的,没有必要每次都访问。如果我们只调用一次animations闭包,给它拍一张快照就可以解决这个问题了,这就要用到@noescape:
func loop(duration:NSTimeInterval,reverse:Bool,@ noescape animations:()->Bool )
这样就不会有保留环问题,因为这个闭包只被执行一次,即便发生循环时也会绕过闭包。@noescape还是个新角色,但是系统库中已经有些地方在使用了,比如我们熟悉的reduce方法:
func reduce<U>(initial: U, combine: @noescape (U, T) -> U) -> U