在 iOS 上,对于 MVVM 中的 DisposeBag,可以放在 ViewModel 中吗?
Posted
技术标签:
【中文标题】在 iOS 上,对于 MVVM 中的 DisposeBag,可以放在 ViewModel 中吗?【英文标题】:On iOS, for the DisposeBag in MVVM, can it be placed in ViewModel? 【发布时间】:2018-05-17 02:59:10 【问题描述】:我是 RxSwift 的新手,在这里我想问一个关于 DisposeBag 应该放在哪里的问题。
我的情况是,我检索了一个在 tableview 中显示的项目列表,每个项目都有自己的标志来指示它是否被选中。
所以我不只是将结果列表绑定到 tableview。当用户通过 tableview 导航时,我需要一些逻辑来编辑本地列表。
我在ViewModel
中创建了一个实例Variable([Item])
,但如果我将逻辑放在ViewModel
中,则需要DisposeBag
。
在谷歌搜索后,大多数具有Variable
实例的 MVVM+RxSwift 示例将DisposeBag
放在ViewModel
中,但有人说它应该只放在ViewController
中。真的吗?如何在ViewModel
中监听Observable
,以便我的业务逻辑可以放在ViewModel
中?
【问题讨论】:
【参考方案1】:DisposeBag
通常不应该不放置在 ViewModel 中,除非有充分的理由。
一般来说,DisposeBag
用于将订阅与其所有者联系起来。通常情况下,ViewModel 不会创建任何订阅,而只是提供 Observables,以便消费者可以订阅它们(例如 ViewController)。
这意味着 ViewController 通常持有DisposeBag
,因为它通常使用订阅(而不是 ViewModel 本身)。
【讨论】:
在我的例子中,API 调用发生在 viewModel 中,那么在 viewModel 中使用 DisposeBag 可以吗?注意:API 调用也是通过 Rx 完成的。 这没有多大意义。是的,网络请求是在视图模型中“声明”的,但消费者是订阅流的人(视图控制器),所以它应该持有 DisposeBag。【参考方案2】:Yes Disposable bag 可以放在 viewModel 里面。哪里有你创建的 observable 就需要 dispose observable 。所以也可以放在 viewModels 里面。由于你是 Rxswift 新手,建议你去看看这个博客进一步清楚 RxSwift: https://medium.com/@arnavgupta180/shift-from-swift-to-rxswift-8dece8af9f4
【讨论】:
Disposability 是一个通用的 RxSwift 概念,但 DisposeBags 通常不是与订阅相关联而不是 Observables 吗?在我看来,规则通常是,无论您订阅一个潜在的非终止序列,您都需要一个 DisposeBag。所以我将这里的基本问题解释为“ViewModel 订阅序列是否可以,还是应该仅限于出售 Observables?”【参考方案3】:您可以在 ViewModel 中放置 Disposable
或 DisposeBag
,这完全取决于您希望订阅何时终止。将它们全部放在一个地方是一种很好的做法,例如前。视图控制器。哪里会更容易处理订阅,因为有时你真的不需要订阅业务逻辑,例如。当滚动视图滚动时,您禁用一个按钮。 (但仍有一些架构,比如 RxMVP,情况正好相反)
在您的情况下,您可以组合 Observables
而不是在 ViewModel 中使用变量。这完全取决于您的需求,但您可以有类似的东西:
class ViewModel
var activeItems: Observable<[Item]>
return Observable.combineLatest(retrieveData(), itemEdited().startWith(nil)) (allItems, editedItem) in
// TODO: check if edited item should be in list
private func retrieveData() -> Observable<[Item]>
return .empty()
private func itemEdited() -> Observable<Item?>
return .empty()
如果您有这些来自 Realm 或 CoreData 的项目,您可以为您的数据库使用 Rx 实现,因此每次修改您的实体时它都会发出一个事件。
【讨论】:
以上是关于在 iOS 上,对于 MVVM 中的 DisposeBag,可以放在 ViewModel 中吗?的主要内容,如果未能解决你的问题,请参考以下文章