在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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容