You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

何时应使用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都没用到,谈何循环引用?完全不需要加。

快速判断步骤

  1. 闭包是否被self强持有,或者被self关联的长期存活对象持有?
  2. 闭包内部是否直接/间接引用了self?
    只有两个条件都满足时,才需要添加[weak self]。

盲目给所有闭包加[weak self]反而可能引发问题:比如闭包执行过程中self被提前释放,导致意外的空值崩溃(虽然可以用guard let self = self处理,但没必要的话纯属冗余)。

内容的提问来源于stack exchange,提问作者nejihen248

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 08:39:47