何时应使用weak self?如何识别需打破循环引用的场景
什么时候该用[weak self]?别再全加了
首先明确:循环引用只在两个对象互相持有强引用时才会发生,判断要不要加[weak self],核心就是看「self 和闭包之间是否形成了双向强引用链」,不用所有闭包都加。
必须加[weak self]的场景
- 闭包被
self强持有(比如是self的存储属性),同时闭包内部强引用self
举个典型例子:
这种情况必须加class ViewController: UIViewController { // self强持有这个闭包 var fetchCompletion: (() -> Void)? func fetchData() { fetchCompletion = { // 闭包内部强引用self,此时形成循环引用:self → fetchCompletion → self self.updateUI() } } }[weak self]打破循环。 - 闭包被外部对象长期持有,且
self持有该外部对象
比如网络请求框架会缓存回调闭包,同时self持有这个请求对象,这时候闭包如果引用self,就会形成self → 请求对象 → 闭包 → self的循环,需要用[weak self]。
完全没必要加[weak self]的场景
- 闭包是临时执行的,执行后立即销毁
比如UIView.animate的闭包、DispatchQueue.main.async的闭包,这些闭包只会在任务完成后就被释放,不会和self形成长期双向持有,不需要加。 - 闭包没有被
self持有,也不会被其他长期存活的对象持有
比如调用全局函数的闭包参数,或者局部变量里的闭包,执行完就被销毁,不会产生循环。 - 闭包内部根本没有引用
self
连self都没用到,谈何循环引用?完全不需要加。
快速判断步骤
- 闭包是否被
self强持有,或者被self关联的长期存活对象持有? - 闭包内部是否直接/间接引用了
self?
只有两个条件都满足时,才需要添加[weak self]。
盲目给所有闭包加[weak self]反而可能引发问题:比如闭包执行过程中self被提前释放,导致意外的空值崩溃(虽然可以用guard let self = self处理,但没必要的话纯属冗余)。
内容的提问来源于stack exchange,提问作者nejihen248
相关产品推荐
相关产品推荐

