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

类中存储的自定义DispatchQueue异步闭包是否需使用weak self?

自定义队列作为类属性时,闭包中必须用weak self吗?

先明确两种场景的核心差异:

  • 直接调用DispatchQueue.global()这类系统全局队列时,队列本身不被当前类持有。闭包里强引用self只会延长self的生命周期到闭包执行完毕,但不会形成循环引用——因为全局队列由系统维护,它不会反过来持有self,所以不用担心内存泄漏。

但如果自定义队列是类的属性(比如示例里的MyClass持有queue),情况完全不同:

  1. MyClass实例通过属性强引用queue
  2. queue.async的闭包会被队列持有,直到闭包执行完成
  3. 若闭包里强引用self,就会形成循环引用链:MyClass实例 → queue → 闭包 → MyClass实例

只要闭包未执行(比如队列任务排队、队列被挂起),这个循环就会持续存在,导致MyClass实例无法被释放,造成内存泄漏。

所以这种场景下,必须用[weak self](配合guard let self或if let self)打破循环引用,避免内存泄漏。

举个反例(不用weak self导致泄漏的情况):

class MyClass {
    let queue = DispatchQueue(label: "MyQueue")
    
    func foo() {
        queue.async {
            // 强引用self,形成循环
            print(self.someProperty)
        }
    }
    
    deinit {
        print("MyClass deinit") // 永远不会触发,内存泄漏
    }
}

// 测试代码
var obj: MyClass? = MyClass()
obj?.foo()
obj = nil // 即使置空,实例也无法被释放

使用[weak self]后,闭包对self是弱引用,循环链被打破:当obj置为nil时,MyClass实例无其他强引用,就能正常被释放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:23:13