如果我的内容如下:
func foo() -> Observable<Foo> {
return Observable.create { observer in
// ...
}
}
func bar() {
foo().observeOn(MainScheduler.instance)
.subscribeNext {
// ...
}
.addDisposableTo(disposeBag)
}
如果我想稍后在bar
中观察到unsubscribe,我该怎么做?
更新
我知道我可以致电dispose
,但根据RxSwift docs:
请注意,您通常不希望手动调用dispose;这只是教育的例子。手动调用处理通常是一种糟糕的代码味道。
unsubscribe
刚刚没有实现?我已经完成了对RxSwift代码的探索,并且在某种程度上我可以理解发生了什么,它看起来不像从订阅方法返回的Disposable
是任何具有有用功能的东西(除了处置)。
答案 0 :(得分:3)
您将Observable
返回的foo
添加到disposeBag
。它在取消分配时处理订阅。
你可以手动&#34;通过调用
disposeBag
disposeBag = nil
你班上的某个地方。
问题编辑后:您希望有选择地取消订阅某些Observable,可能是在满足某些条件时。您可以使用代表这些条件的其他Observable
,并根据需要使用takeUntil
运算符取消订阅。
//given that cancellingObservable sends `next` value when the subscription to `foo` is no longer needed
foo().observeOn(MainScheduler.instance)
.takeUntil(cancellingObservable)
.subscribeNext {
// ...
}
.addDisposableTo(disposeBag)
答案 1 :(得分:1)
由于以上回答的重点是取消订阅特定或特定的可观察对象,因此我将讨论正确,有效地一起取消订阅所有可观察对象。
如何订阅:
this.myVariable$.pipe(takeUntil(this.ngUnsubscribe)).subscribe(value => {
// Do the thing you want to do after there is change in myVariable
});
如何退订:
ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
使用以上ngOnDestroy
,您可以取消所有可观察的订阅。
答案 2 :(得分:1)
如果您想取消订阅可观察的项目,只需重置disposeBag
// Way 1
private lazy var disposeBag = DisposeBag()
//...
disposeBag = DisposeBag()
// Way 2
private lazy var disposeBag: DisposeBag? = DisposeBag()
//...
disposeBag = nil
import UIKit
import RxSwift
class Service {
private lazy var publishSubject = BehaviorSubject<Int>(value: count)
private lazy var count = 0
var counter: Observable<Int> { publishSubject }
func unsubscribeAll() { publishSubject.dispose() }
func increaseCounter() {
count += 1
publishSubject.onNext(count)
}
}
class ViewController: UIViewController {
private lazy var service = Service()
private lazy var disposeBag = DisposeBag()
private weak var navigationBar: UINavigationBar!
override func viewDidLoad() {
super.viewDidLoad()
setupNavigationBar()
subscribeToObservables()
}
}
// MARK: Work with subviews
extension ViewController {
private func setupNavigationBar() {
let navigationBar = UINavigationBar()
view.addSubview(navigationBar)
navigationBar.translatesAutoresizingMaskIntoConstraints = false
navigationBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
navigationBar.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
navigationBar.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
let navigationItem = UINavigationItem()
var barButtons = [UIBarButtonItem]()
barButtons.append(createNavigationItemButton(title: "subscr.", action: #selector(subscribeButtonTapped)))
barButtons.append(createNavigationItemButton(title: "unsubscr.", action: #selector(unsubscribeButtonTapped)))
navigationItem.leftBarButtonItems = barButtons
navigationItem.rightBarButtonItem = createNavigationItemButton(title: "+", action: #selector(increaseCounterNavigationItemButtonTapped))
navigationBar.items = [navigationItem]
self.navigationBar = navigationBar
}
private func createNavigationItemButton(title: String, action: Selector?) -> UIBarButtonItem {
return UIBarButtonItem(title: title, style: .plain, target: self, action: action)
}
}
// MARK: Work with observers
extension ViewController {
private func subscribeToObservables() {
service.counter.subscribe { [weak self] value in
guard let value = value.element,
let navigationItem = self?.navigationBar?.items?.first else { return }
navigationItem.title = "Counter \(value)"
print(value)
}.disposed(by: disposeBag)
}
private func unsubscribeFromObservables() { disposeBag = DisposeBag() }
}
// MARK: Button actions
extension ViewController {
@objc func increaseCounterNavigationItemButtonTapped(_ source: UIBarButtonItem) { service.increaseCounter() }
@objc func subscribeButtonTapped(_ source: UIBarButtonItem) { subscribeToObservables() }
@objc func unsubscribeButtonTapped(_ source: UIBarButtonItem) { unsubscribeFromObservables() }
}
答案 3 :(得分:0)
您可以使用一个新的覆盖disposeBag。如果您需要其他可观察的物体来保持生命,请创建多个disposeBags。如果您考虑一下,这是当一个类被释放时发生的事情→它的disposeBag被释放,释放该类拥有的所有订阅。
示例:
注意:该示例仅说明了原理,我不知道您为什么会像下面这样专门构建某些内容。话虽如此,根据您的体系结构,使用prepareForReuse
清除单元格可能会很有趣。
class MyClass {
var clearableDisposeBag = DisposeBag()
let disposeBag = DisposeBag()
let dependencies: Dependencies
let myObservable: MyObservable
var myOtherObservable: MyOtherObservable?
init(dependencies: Dependencies) {
self.dependencies = dependencies
self.myObservable = dependencies
.myObservable
.subscribe(onNext: doSomething)
.disposed(by: disposeBag)
}
private func doSomething() {/*...*/}
private func doSomethingElse() {/*...*/}
private func subscribeToChanges() {
/// clear previous subscription
clearableDisposeBag = DisposeBag()
/// subscribe again
myOtherObservable = dependencies
.myOtherObservable
.subscribe(onNext: doSomethingElse)
.disposed(by: clearableDisposeBag)
}
}
答案 4 :(得分:-1)
我所做的是创建另一个DisposeBag
var tempBag = DisposeBag()
fun bar() {
foo().subscribe().addDisposable(tempBag)
}
因此,当您想要处置时,您可以在要发布时执行tempBag = nil
。而你还有另一个DisposeBag
让其他一次性用品活着。