我现在正在学习RxSwift。
[什么时候使用.drive(something)
,什么时候.bind(to: something)
?
示例:
let disposeBag = DisposeBag()
let isEnabled = BehaviorRelay(value: true)
let button = UIButton()
// what is the benefit of this:
isEnabled.asDriver().drive(button.rx.isEnabled).disposed(by: disposeBag)
// over this:
isEnabled.bind(to: button.rx.isEnabled).disposed(by: disposeBag)
// or is the above better?
use RxSwift, driver and bind to中的答案并没有帮助。我不明白为什么甚至需要添加asDriver()
才能使它成功运行。
来自RxSwift的GitHub页面
这是最精致的特征。其目的是提供一个在UI层或任何情况下编写反应式代码的直观方式您要在其中建模数据流的地方驱动您的应用程序。
从同一页面再次复制
其预期的用例是对驱动您的申请。
现在回到分歧了吗?
驱动程序确保观察仅发生在主线程上:
Drive是RxSwift的特征之一,可确保仅在MainThread
上发生观察,这意味着无论发出什么线程事件并触发驱动程序,驱动程序始终将确保将事件转发给链中的下一个操作员或其在主线程上的订阅块。
在Rx中,所有事件都在发生事件的同一线程上传播。因此,如果您使用subject.onNext(
在某个线程(100)上触发主题,则直到并且除非您使用observedOn
或subscribedOn
运算符来确保手动进行线程切换,否则将在同一线程(100)上调用其订阅块。
如果您是从viewModel中的可观察对象/对象驱动UI组件,则驱动程序非常有意义。假设您进行API调用以在后台线程上从服务器获取数据,则您不想访问后台线程上的UI组件,无需将可观察对象/对象连接/转换为驱动程序(使用asDriver
并传递onErrorJustReturn
)并驱动您的通过驱动程序的UI组件将确保始终在主线程上访问您的UI组件
无法出错。
通常发生错误时,订阅将被终止,并且如果您驱动的是UI组件,则您不希望您的订阅/绑定在每次发生错误事件时都中断。
示例:假设您通过CoreData驱动tableView,并且由于某些原因从CoreData获取数据时发生错误,如果您不使用驱动器并且使用了平面bind(to:
,则会触发其onError
并绑定与UIComponent一起将被破坏。如果再次获取数据,则必须重新建立此绑定。对于UI组件在获取/获取数据中的错误应该没有任何区别。它应该仅仅是改变其状态的事件流。
[ 您始终可以使用bindTo
只不过是subscribe
上的语法糖衣],因此,如果使用bindTo
或subscribe
来驱动UI组件,则会失去drive
固有的所有优势。] >observedOn
来确保将线程手动切换到main
,并且还可能具有一些重试机制来在发生错误时建立预订回保留/保留预订,但最终您将最终编写自己的驱动器特征
何时使用驱动器,何时使用bindTo
拇指法则是您尝试使用drive
来驱动UI组件,还是使用bindTo
。通常,如果您希望仅在主线程上进行订阅并且不希望订阅出错(例如驱动UI组件),请使用driver
,否则请坚持[C0]或bindTo
编辑1:
OP在评论中的问题:
asDriver()在我的示例中确保isEnabled被观察到主线程,我不必传递onErrorJustReturn因为BehaviorRelay也不会失败?在这种情况下,drive()具有线程收益,而不是故障安全收益?
在我的示例中,确保在主线程上观察到isEnabled-YES
我不必传递onErrorJustReturn,因为BehaviorRelay也不会失败吗? -BINGO
如果您进一步研究BehaviorRelay,则会发现
/// BehaviorRelay是
subscribe
的包装。/// ///与BehaviorSubject
不同,它不能以错误或完成而终止。显然,BehaviorRelay不能出错,因此编译器足够智能,可以理解并且不要求
BehaviorSubject
。如果您真的想使用onErrorJustReturn
,编译器会要求它:)感谢
BehaviorSubject
指出我的错误,该驱动器并不是确保观察仅在Daniel上发生的唯一特征,因此编辑了我的答案以反映同样的情况。谢谢