在ViewController中调用DispatchQueue.main.async时是否需要使用weak self?
DispatchQueue.main.async 搭配 weak self 的合理性说明
结论:你当前的写法是合理的,不属于多此一举,更推荐保留 weak self 的写法
首先解释你没有测出内存泄漏的原因:
DispatchQueue.main.async的闭包是被系统全局的主队列持有,而非你的 ViewController 持有,所以闭包对 self 的强引用是临时的,只要闭包执行完毕就会自动释放对 self 的持有,不会产生双向持有也就是循环引用的问题,这也是你不加 weak 也不会出现永久内存泄漏的核心原因。为什么仍然推荐加 weak self:
- 避免不必要的资源占用与无效操作:如果你的 ViewController 在闭包执行前就已经被销毁(比如用户进入页面后立即返回),未加 weak 的情况下,闭包会一直强持有 self 直到任务执行完毕,相当于给 ViewController 延长了一段无意义的生命周期;而加了 weak 之后,闭包执行时检测到 self 已经为 nil,会直接走 return 逻辑,不会执行后续无意义的 UI 更新操作,也不会额外占用资源。
- 规避后续代码迭代的潜在风险:如果后续你修改代码,将主队列的异步操作替换为当前 ViewController 持有的自定义队列,这时候如果没有提前加 weak self 就会直接产生循环引用,提前保留 weak 写法可以避免这类改代码引发的隐性问题。
关于网传 UIView.animate 不需要加 weak 的说法:
逻辑和主队列异步一致,普通的非重复、时长较短的动画闭包也是临时持有 self,执行完就释放,不会造成永久泄漏;但如果是无限重复、时长很长的动画,加 weak self 仍然可以在 VC 销毁时提前终止相关逻辑,避免不必要的开销。
针对你贴出的代码,现有 [weak self] + 解包的写法没有任何问题,反而更健壮,完全不需要删除。
内容的提问来源于stack exchange,提问作者dreadbot
相关产品推荐
相关产品推荐

