Swift闭包中`self?`与`guard let self`作用是否一致?
关于weak self两种写法的内存管理与行为差异解答
核心结论
guard let self = self else { return }的写法不能100%保证self一定会被释放,但它不会额外造成内存泄漏,同时能解决原写法的逻辑不一致问题,是工程中更推荐的写法。
两种写法的具体差异
原self?写法的问题
- 每一行
self?.xxx调用都会单独做一次弱引用存在性校验,两次校验之间没有原子性保障 - 存在极端场景:第一次调用
self?.set(text: text)时self还存在,执行完成后正好在两行代码的间隙self被释放,导致后续的self?.accessibilityValue = text不会执行,出现逻辑执行不完整的状态不一致问题 - 多次写
self?会冗余,代码可读性更低
guard let self写法的优势
- 闭包执行之初就统一做弱引用解包:如果self已经为nil,直接return跳过所有逻辑,不会出现部分执行的问题
- 解包成功后会持有self的临时强引用,保证闭包执行全程self都存在,所有逻辑可以完整执行
- 不需要重复写
self?,代码更简洁易读
关于内存释放的说明
两种写法都基于[weak self]的声明,本身都不会造成循环引用:
- 原写法不会持有self,每次访问都是临时读取弱引用
guard let self的强引用只作用于当前闭包的执行周期,闭包执行完毕后就会自动释放这个强引用,不会永久持有self
唯一的例外场景:如果承载闭包的序列本身因为disposeBag未释放、序列一直未终止也未被主动dispose,导致闭包被永久持有且一直触发执行,才会出现每次闭包执行时临时持有self的情况,但只要闭包执行结束就会释放,不会造成self永久泄漏。
内容的提问来源于stack exchange,提问作者bruno
相关产品推荐
相关产品推荐

