在含self弱引用捕获列表的闭包中,是否需显式指定self?
在含self弱引用捕获列表的闭包中,是否需显式指定self?
嘿,这个问题问到点子上了,很多刚接触Swift闭包捕获逻辑的开发者都会有这个疑惑,我给你一步步理清楚:
首先先回顾下你提到的场景:
最开始的代码因为闭包隐式捕获了self,Swift为了提醒你注意捕获语义,抛出了Implicit use of 'self' in closure; use 'self.' to make capture semantics explicit这个错误。
当你改成带[weak self]捕获列表,再用guard let self = self else { return }之后,这里的self其实是闭包内部的一个局部强引用常量——它是对弱引用self的一次临时强绑定,但这个绑定只在闭包的当前作用域内有效,不会导致外部的self被额外持有(也就不会产生循环引用)。
那重点来了:当你在guard let之后直接写view.setNeedsLayout(),现代Swift完全能正确识别这个view是属于刚才绑定的局部self的,它不会再去隐式捕获外部的self,也就不会产生意外的强引用。
换句话说,下面这两段代码的效果是完全一样的,都是安全的:
DispatchQueue.main.async { [weak self] in guard let self = self else { return } self.view.setNeedsLayout() }
DispatchQueue.main.async { [weak self] in guard let self = self else { return } view.setNeedsLayout() }
Swift的编译器在这种场景下足够智能,它能理解你在guard let绑定了self之后,作用域内的属性访问都是基于这个局部self的,不需要你每次都显式写self.——当然,如果你愿意写的话也完全没问题,只是没必要而已。
备注:内容来源于stack exchange,提问作者bart
相关产品推荐
相关产品推荐

