ios - 完成块内的 RxSwift 订阅问题
问题描述
我有一个真正的具体问题。我通常得到这个,我找不到原因。
主要问题,即使我多次使用 disposeBag 一些“订阅(onNext:”调用。但我发现了一些东西;调用计数线性增加取决于另一个订阅。
例如; 我有两个组件,在 viewController 上声明。如果这是一个自定义集合视图,另一个是自定义刷新控制管理器。
self.kpiesCollectionView.collectionHeaderButton.rx.tap
. subscribe(onNext: { [weak self] _ in
// Push to next ViewController
}).disposed(by: self.kpiesCollectionView.disposeBag)
refreshControl.rx.controlEvent(UIControlEvents.valueChanged).asObservable().subscribe(onNext: { () in
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
completion()
}
}).disposed(by: disposeBag)
refreshControl 工作自行处理。它只是将完成返回给 viewController。所以我在 self 中调用 disposeBag。
场景是这样的;
单击按钮 -> 推送到 VC(1 次)
下拉刷新
单击按钮 -> 推送到 VC(2 次)Pull-To-Refresh
单击按钮 -> 推送到 VC(3 次)
更新
我发现了问题。这就是为什么,我也更新了标题。原因是我self.kpiesCollectionView.collectionHeaderButton.rx.tap.subscribe(
在我的请求完成块内使用,但是当我移到它外面时,它运行良好。
也许它不是正确的地方,但是,只是想学习。我怎样才能避免这种情况。?即使在块内,我如何调用 subscribe() ?
解决方案
我决定在这里发布答案,也许其他 SO 用户会觉得它有帮助。因此,如果您的代码在subscribe:onNext
没有观察者发送命令的情况下被多次调用onNext
,这意味着您多次订阅了观察者。
现在dispose(bag:)
将在释放包被释放时释放任何订阅者,但如果包仍然存在于您的对象上,则订阅者将不会被释放,此外,对于 UI 订阅者(在视图控制器、视图等中),这是最佳实践使用week self
内部onNext:/onError/etc
以避免您的包/控制器的保留周期。
要“强制”处理一个袋子,您有三个选择:
- 如果您使用
DisposeBag
它就足以重新初始化包(bag = DisposeBag()
)。 - 有一个
CompositeDisposable
像字典一样工作的包,这种包让你可以更精确地控制你可以处理的东西,每当你在包中添加一个 disposeble(bag.insert
,你会得到那个一次性的钥匙,你可以remove
使用它来调用钥匙; 最后一个选项,有时更像是丑陋的选项,是保留对一次性的引用并直接在其上调用 dispose,例如:
var myDisposable: Disposable? = nil ...... fun iWantToSubscribe() { myDispsable?.dispose() myDisposable = myObserver.subscribe(onNext: {}) }
推荐阅读
- django - Django ORM:误导`prefetch_related`的`first()`
- visual-studio - 如何从自定义 NuGet 包运行 EF 迁移?
- reactjs - 何时使用反应组件函数之外的变量而不是状态
- paraview - 在 paraview 中为 polydata 分配颜色
- java - 使用 Keycloak Java API 重置用户密码
- python - 用 datetime.timedelta(hours=1) 添加小时
- arrays - MongoDB比较子数组
- julia - 在 Julia 中提取子字符串
- typescript - TypeScript 历史方法类型
- c - 使用 pow 函数时如何避免 -nan(ind) 错误。是否可以使用具有非整数指数的负基数的 pow