Retain Cycle in Swift

这里需要一张图

闭包

var closure: (() -> Void) = { 
    [weak self] in              // [unowned self]
    self?.xxxxx....
}

weakunowned区别请自己看官方文档。

‘不正常’的闭包

var closure: (() -> Void)?

override func viewDidLoad() {
    super.viewDidLoad()
    closure = normal
}

func normal() {
    self.xxxxx...
}

Swift中是可以将func赋值给闭包的,这样的情况下,也是会产生循环引用的。那么这样子的要怎么去解决呢?weak?

 func normal() {
    [weak self] in   // 编译器报错
   self?.xxxxx...
}

解决方法一

stackoverflow有人已经给出了解决方案。

将执行的func放在闭包内,然后执行闭包时再执行func,这样就可以将传入的self,变成weak.

func methodPointer<T: AnyObject>(obj: T, method: @escaping (T) -> () -> Void) -> (() -> Void) {
    return { [weak obj] in
        method(obj!)()
    }
}

closure = methodPointer(obj: self, method: DetailViewController.normal)

解决方法二

Lammert Westerhoff在他的blog里也介绍了另一种方法。

在一个类里的情况下,声明时直接将func赋给闭包,并且添加lazy。不过这种方式局限性比较大。

lazy var closure: (() -> Void) = self.normal

结语

有bug欢迎及时提出~
有问题欢迎及时提出~
有新的解决方法欢迎及时提出~

参考资料

Make self weak in methods in Swift
function-references-in-swift-and-retain-cycles

推荐阅读更多精彩内容