Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 在任何情况下都有必要叫“disposed(by:)”吗?_Swift_Rx Swift - Fatal编程技术网

Swift 在任何情况下都有必要叫“disposed(by:)”吗?

Swift 在任何情况下都有必要叫“disposed(by:)”吗?,swift,rx-swift,Swift,Rx Swift,作为标题,在任何情况下都有必要调用disposed(by:)?若有,原因为何 考虑这样一个简单的例子: class ViewController: UIViewController { let button = UIButton() override func viewDidLoad() { button.rx.tap.bind(onNext: { _ in print("Button tapped!") }) // Does t

作为标题,在任何情况下都有必要调用
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?
  }
}

不,在任何情况下都不必调用
.disposed(by:)

如果您知道某个可观察对象最终将发送一个停止事件,并且您知道您希望继续收听该可观察对象,直到它发送停止事件为止,则没有理由/需要处置订阅,因此无需将一次性订阅插入处置包


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

如果调用代码没有处理订阅,并且源observable没有发送停止事件,那么订阅将继续运行,即使所有其他相关代码都丢失了对订阅中涉及的对象的所有引用

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

_ = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
    .subscribe(onNext: { print($0) })
\=Observable.interval(.seconds(1),调度程序:MainScheduler.instance)
.subscribe(onNext:{print($0)})
在创建值的视图控制器不再存在后,上面的代码将继续打印值

在您介绍的示例中,UIButton对象在被取消初始化时将发出一个已完成的事件,因此,如果您想一直听按钮直到发生这种情况,则无需将一次性文件放在处置袋中


忽略一次性物品意味着你需要非常清楚哪些是完整的,哪些是不完整的,但是如果你有这样的理解,你可以忽略它们。请记住,下一个开发人员或未来的您对代码的理解不会像您一样好。

是,例如,当您希望在创建控制器被销毁时销毁侦听器是,只是因为当您查看控制器时,会解除分配
disposebag
,内存会被清理,也不会形成保留周期。但在上面的简单示例中,您不需要disposebag。解除分配视图控制器时,将解除订阅。使用DisposeBag是一种良好的做法,但并非总是必要的。还有其他处理订阅的方法,例如takeUntil。你可以读更多。@Fabioflici是的。而按钮
点击
序列在内部使用
takeUntil
。这就是为什么我上面的例子很好。我100%同意你的观点。我刚刚意识到,
tap
序列在内部使用了
takeUntil
,这就是为什么当按钮离开时,资源将被释放。我认为有很多人知道他们应该使用
disposed(by)
,但并不真正理解背后的原因。非常感谢您如此详细的回答。