在closure中处理循环引用

Swift是一们安全的语言,对于Objective-C中经常出现的block引起的循环引用问题处理的更好,在closure中引用成员属性的时候,会强制使用self,否则编译不过。如下代码:

class TestClass {
    var name: String = "aa"
    func viewDidLoad() {
        testEmbededFunction { () -> () in
            name = "bb"
        }
    }

    func testEmbededFunction(f: ()->()) {
        f()
    }
 }

上面的代码会出现编译错误,提示信息如下:

error.png

苹果官方解释如下:

Swift requires you to write self.someProperty or self.someMethod() (rather than just someProperty or someMethod()) whenever you refer to a member of self within a closure. This helps you remember that it's possible to capture self by accident

是因为closure中capture了self,如果self再引用closure的话,就会导致循环引用。因此解决循环引用就有两种方式:
1、保证closure不会强引用self
2、保证self不会强引用closure

第一种情况的解决办法:
使用capture list来解决[weak self, unowned self]

第二种情况的解决办法,
在Swift中可以使用@noescape来保证这一点,比如这样定义方法就没事了:

func testEmbededFunction(@noescape f: ()->()) { 
  f() 
}

官方文档中对noescape的描述:

Apply this attribute to a function or method declaration to indicate that a parameter it will not be stored for later execution, such that it is guaranteed not to outlive the lifetime of the call. Function type parameters with the noescape declaration attribute do not require explicit of self. for properties or method

推荐阅读更多精彩内容