RxSwift中Driver为何不会产生循环引用?
RxSwift中Driver不会产生循环引用的原因解析
你的两段代码的差异本质在于是否形成强引用闭环,而非Driver本身存在特殊的弱引用处理逻辑,以下是具体分析:
第二段代码内存泄漏的原因
这段代码中,你在subscribe的闭包内通过[self]显式强引用了ViewController:
publishRelay .subscribe(onNext: { [self] _ in self.publishRelay2.onNext("") }) .disposed(by: disposeBag)
形成的强引用链为:
- ViewController 强持有
publishRelay和disposeBag publishRelay强持有订阅闭包(RxSwift的订阅逻辑中,序列会持有订阅回调闭包)- 闭包通过
[self]强持有 ViewController
这个闭环会导致ViewController的引用计数永远无法降为0,disposeBag无法被释放、订阅也不会销毁,最终造成内存泄漏,ViewController无法执行deinit。
第一段代码能正常释放的原因
再看使用drive的代码:
publishRelay .asDriver(onErrorJustReturn: "") .drive(self.publishRelay2) .disposed(by: disposeBag)
这里的引用关系是:
- ViewController 强持有
publishRelay、publishRelay2和disposeBag publishRelay(经asDriver转换后的序列)通过drive订阅,强持有观察者publishRelay2publishRelay2是ViewController的属性,但它本身不会反向持有ViewController(Relay仅作为事件容器,不持有其所有者)
此时并未形成闭环:当ViewController的外部引用被移除后,其引用计数降为0,disposeBag会被释放,进而销毁所有绑定的订阅,publishRelay对publishRelay2的强引用被断开,整个引用链被打破,ViewController可以正常执行deinit。
为什么查看drive源码看不到弱引用?
因为完全不需要。drive的核心是将序列绑定到观察者,而非通过闭包捕获self。你传递的self.publishRelay2只是把观察者对象传给序列,观察者本身不持有ViewController,自然不会产生循环引用,也就不需要额外的弱引用处理。
如果把第二段代码改成弱引用捕获self,同样可以避免内存泄漏:
publishRelay .subscribe(onNext: { [weak self] _ in guard let self = self else { return } self.publishRelay2.onNext("") }) .disposed(by: disposeBag)
内容的提问来源于stack exchange,提问作者Choijun0
相关产品推荐
相关产品推荐

