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

闭包中是否必须用guard let self?DispatchQueue.main需加[weak self]吗?

Swift闭包中self捕获的常见问题解答

闭包是异步流程里的常用工具,但不少开发者的写法其实没必要,先看两个典型例子:

异步加载数据的冗余写法

很多人会写这样的代码:

final class ViewController {
    private func bind() {
        self.viewModel.loadData { [weak self] in
            guard let self else { return } 
            self.doSomething()
        }
    }
}

但如果你的需求只是“self存在时才执行方法,不存在就跳过”,完全可以简化成:

self.viewModel.loadData { [weak self] in
    self?.doSomething()
}

guard let self的作用是给外部的弱引用创建一个强引用,保证闭包执行期间self不会被释放,但如果只是单条方法调用,可选链已经能满足需求,没必要多这一层guard。

主队列异步的过度谨慎写法

还有开发者会这么处理主队列的异步闭包:

DispatchQueue.main.async { [weak self] in
    guard let self else { return }
    self.updateUI()
}

但实际上DispatchQueue.main根本不会强持有任何对象,哪怕省略[weak self]也不会产生循环引用,直接这么写就完全没问题:

DispatchQueue.main.async {
    self.updateUI()
}

接下来直接解答两个核心疑问:

疑问1:必须在所有闭包内用guard let self else { return }吗?

当然不用。要不要加这个guard完全看你的业务场景:

  • 如果闭包里有好几处需要用到self,用guard let self可以避免反复写self?,让代码更清爽;
  • 如果只是单条依赖self的方法调用,用可选链self?.xxx()就足够,多写guard纯属冗余;
  • 核心原则:只有当你需要确保闭包执行期间self不会被释放,或者想简化多段self相关代码时,才需要用guard let self,它不是所有闭包的标配写法。

疑问2:DispatchQueue.main的闭包里需要加[weak self]吗?

不需要。原因很直接:循环引用的前提是两个对象互相强持有,但self不会持有DispatchQueue,DispatchQueue也不会长期持有self——它只是临时持有闭包,闭包执行完毕就会释放self的引用,根本不会形成循环。

当然,如果你的闭包执行时间特别长,担心拖慢self的释放节奏,也可以考虑用[weak self],但这属于优化场景,不是必须的常规操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 21:34:52