在任何情况下都需要调用“dispose(by:)”吗?

con*_*gnd 3 swift rx-swift

disposed(by:)正如标题所示,无论如何都需要调用吗?如果是,为什么?

考虑一个像这样的简单例子:

class ViewController: UIViewController {
  let button = UIButton()

  override func viewDidLoad() {
    button.rx.tap.bind(onNext: { _ in
      print("Button tapped!")
    })
    // Does this make any retain cycle here?
  }
}
Run Code Online (Sandbox Code Playgroud)

Dan*_* T. 5

不,不必.disposed(by:)在所有情况下都致电。

如果你有一个 Observable,你知道它最终会发送一个停止事件,并且你知道你想继续监听该 Observable,直到它这样做,那么没有理由/需要处置订阅,因此不需要插入一次性放入处置袋中。


返回 Disposable 的原因是调用代码可以在observable 完成之前.subscribe结束订阅。调用代码通过调用返回的一次性对象来结束订阅。否则,订阅将继续,直到源可观察对象发送停止事件(完成或错误)。dispose()

如果调用代码不处理订阅,并且源可观察对象不发送停止事件,则订阅将继续运行,即使涉及的所有其他代码已丢失对订阅中涉及的对象的所有引用。

例如,如果将其放入 viewDidLoad 中:

_ = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
    .subscribe(onNext: { print($0) })
Run Code Online (Sandbox Code Playgroud)

在创建它的视图控制器不再存在之后,上面的代码将继续打印值。

在您提供的示例中,UIButton 对象在取消初始化时发出已完成事件,因此如果您想在该事件发生之前监听按钮,则无需将一次性物品放入处置袋中。

忽略一次性意味着您需要非常了解哪些 Observables 已完成,哪些未完成,但如果您有这种了解,则可以忽略它们。请记住,下一个开发人员或未来的您不会像您一样对代码有很好的理解。

  • 我100%同意你的观点。我刚刚意识到“tap”序列在内部使用“takeUntil”,这就是为什么当按钮消失时资源将被释放。我认为有很多人知道他们应该使用“dispose(by)”,但并不真正理解其背后的原因。非常感谢如此超级详细的回答。 (2认同)