知识卡片
闭包捕获self同样制造循环强引用
内容
[[闭包捕获变量形成持久化状态]]提到闭包会持续引用它捕获的外层变量;如果一个类实例把某个闭包存成自己的属性,而这个闭包内部又访问了self(从而强引用捕获self),就构成了实例→闭包属性→闭包捕获的self→实例本身的循环强引用,和两个类实例互相强引用是同一类问题,只是中间多绕了一层闭包。这种情况尤其容易被忽略,因为闭包看起来不像一个”持有引用的对象”,但它在被捕获变量这件事上和类实例毫无区别。解法思路与[[循环强引用与weak打破所有权倒置]]一致:在闭包捕获列表里把self标记为weak(或unowned,取决于闭包和self谁的生命周期更长),让闭包对self的引用不计入引用计数,交由外部的其他强引用决定self何时该被释放。
参考来源
《Swift编程权威指南》第24章《内存管理和ARC》