将 ViewModelOwners 与 ReactiveCocoa 一起使用时如何处理 DisposeBag
How to dispose DisposeBag when using ViewModelOwners with ReactiveCocoa
ViewModelOwners 记录如何使用 ReactiveCocoa CompositeDisposable
Example 甚至是用 ReactiveCocoa 实现的。
但是,我不明白 disposeBag
是如何实际处理的,因为 CompositeDisposable
不会在 deinit
上自动处理
我正在尝试这个例子并向一次性文件添加一条日志消息:
func didSetViewModel(_: ViewModel, disposeBag: CompositeDisposable) {
disposeBag += AnyDisposable {
print("Disposed Profile")
}
}
当控制器被解除分配时从不打印该消息。
我认为你需要在 deinit
上手动处理包,但是关联的对象没有暴露,所以我无法在 deinit
中获取 disposeBag
。
我想出的最好的方法是像这样使用 ReactiveCocoa 中的 lifetime
:
func didSetViewModel(_: ViewModel, disposeBag: CompositeDisposable) {
disposeBag += AnyDisposable {
print("Disposed Profile")
}
self.reactive.lifetime.observeEnded {
if !disposeBag.isDisposed {
disposeBag.dispose()
}
}
}
但这似乎有问题,例如如果这是 ReusableViewModelOwner
,那么所有 但 最后一个 disposeBags 已经被处理掉了,但我仍然保留它们...
基本上,我的问题是:您应该如何将 ViewModelOwners
与 ReactiveCocoa.CompositeDisposable
一起使用?
如问题中所述,ReactiveSwift.CompositeDisposable
不会在 deinit 时自动处置。
但是 ReactiveSwift 已经有了一个解决方案:ScopedDisposable
正是这样做的。
所以原始问题的解决方案是,使用 ScopedDisposable<CompositeDisposable>
而不是普通的 CompositeDisposable
:
extension ScopedDisposable: ViewModelOwnerDisposeBagProtocol where Inner == CompositeDisposable {
public convenience init() {
self.init(CompositeDisposable())
}
private final class Wrapper: Disposable {
var isDisposed: Bool
let disposable: ViewModelOwnerDisposable
init(_ disposable: ViewModelOwnerDisposable) {
self.disposable = disposable
isDisposed = false
}
func dispose() {
disposable.dispose()
isDisposed = true
}
}
public func add(_ disposable: ViewModelOwnerDisposable) {
inner.add(Wrapper(disposable))
}
}
然后
func didSetViewModel(_ viewModel: ViewModel, disposeBag: ScopedDisposable<CompositeDisposable>) {
disposeBag += AnyDisposable {
print("Disposed Profile")
}
}
文档已经相应更新
ViewModelOwners 记录如何使用 ReactiveCocoa CompositeDisposable
Example 甚至是用 ReactiveCocoa 实现的。
但是,我不明白 disposeBag
是如何实际处理的,因为 CompositeDisposable
不会在 deinit
我正在尝试这个例子并向一次性文件添加一条日志消息:
func didSetViewModel(_: ViewModel, disposeBag: CompositeDisposable) {
disposeBag += AnyDisposable {
print("Disposed Profile")
}
}
当控制器被解除分配时从不打印该消息。
我认为你需要在 deinit
上手动处理包,但是关联的对象没有暴露,所以我无法在 deinit
中获取 disposeBag
。
我想出的最好的方法是像这样使用 ReactiveCocoa 中的 lifetime
:
func didSetViewModel(_: ViewModel, disposeBag: CompositeDisposable) {
disposeBag += AnyDisposable {
print("Disposed Profile")
}
self.reactive.lifetime.observeEnded {
if !disposeBag.isDisposed {
disposeBag.dispose()
}
}
}
但这似乎有问题,例如如果这是 ReusableViewModelOwner
,那么所有 但 最后一个 disposeBags 已经被处理掉了,但我仍然保留它们...
基本上,我的问题是:您应该如何将 ViewModelOwners
与 ReactiveCocoa.CompositeDisposable
一起使用?
如问题中所述,ReactiveSwift.CompositeDisposable
不会在 deinit 时自动处置。
但是 ReactiveSwift 已经有了一个解决方案:ScopedDisposable
正是这样做的。
所以原始问题的解决方案是,使用 ScopedDisposable<CompositeDisposable>
而不是普通的 CompositeDisposable
:
extension ScopedDisposable: ViewModelOwnerDisposeBagProtocol where Inner == CompositeDisposable {
public convenience init() {
self.init(CompositeDisposable())
}
private final class Wrapper: Disposable {
var isDisposed: Bool
let disposable: ViewModelOwnerDisposable
init(_ disposable: ViewModelOwnerDisposable) {
self.disposable = disposable
isDisposed = false
}
func dispose() {
disposable.dispose()
isDisposed = true
}
}
public func add(_ disposable: ViewModelOwnerDisposable) {
inner.add(Wrapper(disposable))
}
}
然后
func didSetViewModel(_ viewModel: ViewModel, disposeBag: ScopedDisposable<CompositeDisposable>) {
disposeBag += AnyDisposable {
print("Disposed Profile")
}
}
文档已经相应更新