闭包产生循环引用的前提:
(1)将闭包赋值给一个类的属性。
(2)这个背包中访问了实例的某个属性或者方法。
这中情况导致闭包捕获了self,而self强引用了闭包。这就导致了循环引用。
解决方案:
定义捕获列表:在定义闭包时,同时定义捕获列表作为参数的一部分。通过这种方式可以解决闭包和类实例之间的循环强引用。捕获列表定义了闭包体内捕获一个或者多个引用类型的规则。跟解决两个实例间的循环强引用一样,声明每个捕获的引用为弱引用或者无主引用,而不是强引用。应根据代码关系来决定使用弱引用还是无主引用。
如果闭包没有指明参数列表或者参数类型,即他们会通过上下文进行推断。那么可以把捕获列表和关键字in放在闭包最开始的地方。
如果闭包有参数和返回值类型,把捕获放在他们前面。
到底是采用unowned还是采用self?当闭包和捕获的实例总是同时销毁,将闭包内的捕获定义为无主引用。相反的,在捕获的引用可能变为nil时,将闭包内的捕获定义为弱引用。弱引用总是可选类型,而且当引用的实例被销毁后,弱引用的值会自动置为nil。这使我们可以在闭包体内检查他们是否存在。