Swift中[weak self]在guard语句绑定为何升级为强引用?
为什么闭包中要把weak self升级为strongSelf?
先看你贴的这段代码:
networkRequest.fetchData() { [weak self] result in guard let strongSelf = self else { return } switch result { case .Succeeded(let data): strongSelf.processData(data) case .Failed(let err): strongSelf.handleError(err) } }
这里的核心逻辑要从Swift的引用类型和闭包捕获规则说起:
1. 为什么一开始要用[weak self]?
闭包如果直接捕获self的强引用,很容易造成循环引用:比如self持有networkRequest,networkRequest又持有这个闭包,闭包再持有self,三者形成引用环,导致对象永远无法被释放。用[weak self]是告诉闭包:我只持有self的弱引用,不会增加它的引用计数,这样就打破了循环引用的可能。
2. 弱引用的问题是什么?
弱引用的特点是:当对象被释放时,弱引用会自动变成nil,而且每次访问弱引用的变量时,都可能拿到nil——哪怕你上一行刚判断过它不是nil,下一行访问时对象也可能已经被其他线程释放了。
比如如果不用strongSelf,直接这么写:
networkRequest.fetchData() { [weak self] result in if self != nil { // 这里可能崩溃:因为判断完到执行这行的间隙,self可能已经被释放成nil self!.processData(data) } }
这种写法是不安全的,存在潜在的崩溃风险。
3. guard let strongSelf = self到底做了什么?
这行代码其实完成了两个关键操作:
- 检查存活状态:判断当前
weak self指向的对象是否还存在(不是nil),如果已经释放,直接进入else分支返回,闭包不再执行后续逻辑。 - 升级为强引用:如果对象还存活,就创建一个指向该对象的强引用,并赋值给
strongSelf。强引用会把对象的引用计数+1,只要strongSelf还存在(也就是闭包执行的整个周期内),这个对象就不会被释放。
这样一来,闭包里后续用strongSelf调用方法时,就不用担心对象突然被释放的问题,保证了代码执行的安全性。
一句话总结
用[weak self]避免循环引用,用strongSelf保证闭包执行期间对象不会被意外释放,两者结合是Swift中处理闭包捕获self的标准安全写法。
内容的提问来源于stack exchange,提问作者zztkm
相关产品推荐
相关产品推荐

