Swift嵌套闭包中是否需要二次声明[weak self]?
结论先行
两种写法都不会造成内存泄漏,核心差异在于第二层闭包对self的捕获行为,没有绝对的对错,按需选择即可。
两种写法的区别
1. 仅外层声明[weak self]
内层闭包没有显式声明捕获规则时,会自动捕获外层闭包中的weak self变量,本质上依然是对self对象的弱引用,不会产生强持有环。
但要注意一个特殊情况:如果你在外层闭包中先将weak self解包为强引用,再调度内层闭包,那么内层捕获的就是这个强引用的self,会临时持有self对象直到内层闭包执行完成:
AVCaptureDevice.requestAccess(for: AVMediaType.video) { [weak self] response in guard let self = self else { return } // 这里先解包成强引用 DispatchQueue.main.async { // 这里捕获的是上面的强self,会持有self直到闭包执行完 self.updateUI() } }
这种场景适合需要保证内层闭包执行时self一定存活的业务,比如用户触发了拍照请求,只要没退出页面就必须弹结果提示。
2. 两层都声明[weak self]
内层显式加[weak self]时,相当于直接对原始self对象做弱引用,不受外层闭包是否提前解包强持有self的影响,只要self对象被释放,内层闭包就会拿到nil直接提前返回。
这种写法更保守,后续修改外层代码时也不会意外导致self被延长生命周期,更适合内层闭包执行与否不影响核心逻辑的场景,比如页面统计、非强制的UI更新。
通用推荐
如果没有特殊的业务要求,两层都写[weak self]是更稳妥的写法,不会有额外开销,也能避免后续代码迭代不小心引入的内存问题。
内容的提问来源于stack exchange,提问作者Cheok Yan Cheng
相关产品推荐
相关产品推荐

