在使用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