RxSwift与最近的怪异行为有关

RxSwift与最近的怪异行为有关,swift,reactive-programming,rx-swift,reactivex,Swift,Reactive Programming,Rx Swift,Reactivex,今天我将代码从ReactiveSwift迁移到RxSwift,遇到了这个奇怪的场景 我在一个ViewModel类中有一个observatable由withLatestFrom操作符组成,它只在编写时我在ViewModel类的初始值设定项中所做的测试订阅上发出,而不是在ViewController中所做的订阅上发出 此可观察对象中的withLatestFrom运算符正在接受另一个Observable,该运算符也是以withLatestFrom运算符作为参数组成的。 下面是我用来展示这种奇怪行为的

今天我将代码从ReactiveSwift迁移到RxSwift,遇到了这个奇怪的场景

我在一个
ViewModel
类中有一个
observatable
withLatestFrom
操作符组成,它只在编写时我在
ViewModel
类的初始值设定项中所做的测试订阅上发出,而不是在
ViewController
中所做的订阅上发出

此可观察对象中的
withLatestFrom
运算符正在接受另一个
Observable
,该运算符也是以
withLatestFrom
运算符作为参数组成的。

下面是我用来展示这种奇怪行为的代码,您可以在XCode中运行它,并将调试器输出过滤器设置为
[!]
,以忽略模拟器生成的garbagge输出:

导入UIKit
导入RxSwift
公共最终类RxTestViewModel{
公共init(){
//当viewDidLoad发出时,使用短语发出配置
让configPhrases=self.viewDidLoadSubject
.withLatestFrom(使用短语对象自行配置)
.filter{$0!=nil}
.map{$0!}
//显示要在viewDidLoad上打印的短语
self.toBePrinted=configPhrases.asObservable()
_=self.toBePrinted.subscribe(onNext:{
打印(“[!][\(Thread.current)]--ViewModel.toBePrinted.onNext->\($0)”)
})
//每当调用buttonTapped()时打印第一个短语
self.printSomething=self.buttonAppedSubject
.withLatestFrom(self.configureWithPhraseSObject
.filter{$0!=nil}
.map{$0!})
_=self.printSomething.subscribe(onNext:{
打印(“[!][\(Thread.current)]--ViewModel.printSomething.onNext->\($0)”)
})
}
//标记:输入
private let ConfigureWithphrassObject=BehaviorSubject(值:nil)
公共函数配置为(短语:[字符串]){
打印(“[!][\(Thread.current)]--ViewModel.configureWith”)
self.configurewithphrassubject.on(.next(短语))
}
private let viewDidLoadSubject=PublishSubject()
public func viewDidLoad(){
打印(“[!][\(Thread.current)]--ViewModel.viewDidLoad”)
在(.next(())上的self.viewDidLoadSubject.on
}
private let buttonappedsubject=PublishSubject()
公共函数按钮(){
打印(“[!][\(Thread.current)]--ViewModel.buttonTapped”)
在(.next(())上的self.buttonAppedSubject.on
}
//标记:输出
公共事物:可见的
公共租赁许可证:可观察
}
公共最终类RxTestViewController:UIViewController{
私有let按钮:UIButton=UIButton()
私有let viewModel:RxTestViewModel=RxTestViewModel()
公共静态func instantiate()->RxTestViewController{
设vc=RxTestViewController()
vc.viewModel.configureWith(短语:[“第一短语”、“第二短语”、“第三短语”])
返回vc
}
}
扩展RxTestViewController{
公共覆盖函数viewDidLoad(){
super.viewDidLoad()
self.setupButton()
self.setupViewModel()
self.viewModel.viewDidLoad()
}
}
扩展RxTestViewController{
专用函数setupViewModel(){
_=self.viewModel.toBePrinted
.subscribeOn(ConcurrentMainScheduler.instance)
.订阅(onNext:{
打印(“[!][\(Thread.current)]--RxTestViewController.toBePrinted.onNext->\($0)”
self.viewModel.buttonTapped()
})
_=self.viewModel.printSomething
.subscribeOn(ConcurrentMainScheduler.instance)
.订阅(onNext:{
打印(“[!][\(Thread.current)]--RxTestViewController.printSomething.onNext->\($0)”)
})
}
}
扩展RxTestViewController{
专用功能设置按钮(){
//添加到视图
self.view.addSubview(self.button)
//按钮配置
self.button.setTitle(“单击我”,表示:。正常)
self.button.addTarget(self,action:#选择器(带按钮),用于:。touchUpInside)
//自动布局
self.button.translates自动调整大小gmaskintoConstraints=false
NSLayoutConstraint.activate([
self.button.centerXAnchor.constraint(等于:self.view.centerXAnchor),
self.button.centerYAnchor.constraint(等式:self.view.centerYAnchor)])
}
@objc
私有函数按钮(){
self.viewModel.buttonTapped()
}
}
预期结果应为:

[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.configureWith
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.viewDidLoad
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.toBePrinted.onNext -> ["First phrase", "Second phrase", "Third phrase"]
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- RxTestViewController.toBePrinted.onNext -> ["First phrase", "Second phrase", "Third phrase"]
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.buttonTapped
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.printSomething.onNext -> ["First phrase", "Second phrase", "Third phrase"]
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- RxTestViewController.printSomething.onNext -> ["First phrase", "Second phrase", "Third phrase"]
[!][{number=1,name=main}]--ViewModel.configureWith
[!][{number=1,name=main}]--ViewModel.viewDidLoad
[!][{number=1,name=main}]--ViewModel.toBePrinted.onNext->[“第一句话”、“第二句话”、“第三句话”]
[!][{number=1,name=main}]--RxTestViewController.toBePrinted.onNext->[“第一个短语”、“第二个短语”、“第三个短语”]
[!][{number=1,name=main}]--ViewModel.buttonTapped
[!][{number=1,name=main}]--ViewModel.printSomething.onNext->[“第一个短语”、“第二个短语”、“第三个短语”]
[!][{number=1,name=main}]--RxTestViewController.printSomething.onNext->[“第一个短语”、“第二个短语”、“第三个短语”]
但我得到的却是:

[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.configureWith
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.viewDidLoad
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.toBePrinted.onNext -> ["First phrase", "Second phrase", "Third phrase"]
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- RxTestViewController.toBePrinted.onNext -> ["First phrase", "Second phrase", "Third phrase"]
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.buttonTapped
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.printSomething.onNext -> ["First phrase", "Second phrase", "Third phrase"]
[!][{number=1,name=main}]--ViewModel.configureWith
[!][{number=1,name=main}]--ViewModel.viewDidLoad
[!][{number=1,name=main}]--ViewModel.toBePrinted.onNext->[“第一句话”、“第二句话”、“第三句话”]
[!][{number=1,name=main}]--RxTestViewController.toBePrinted.onNext->[“第一个短语”、“第二个短语”、“第三个短语”]
[!][{number=1,name=main}]--ViewModel.buttonTapped
[!][{number=1,name=main}]--ViewModel.printSomething.onNext->[“第一个短语”、“第二个短语”、“第三个短语”]
如您所见,在
ViewController
上不调用observer订阅,只在
ViewModel
上调用

[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.configureWith
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.viewDidLoad
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.toBePrinted.onNext -> ["First phrase", "Second phrase", "Third phrase"]
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- RxTestViewController.toBePrinted.onNext -> ["First phrase", "Second phrase", "Third phrase"]
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.buttonTapped
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.printSomething.onNext -> ["First phrase", "Second phrase", "Third phrase"]
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- RxTestViewController.printSomething.onNext -> ["First phrase", "Second phrase", "Third phrase"]
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.configureWith
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.viewDidLoad
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.toBePrinted.onNext -> ["First phrase", "Second phrase", "Third phrase"]
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- RxTestViewController.toBePrinted.onNext -> ["First phrase", "Second phrase", "Third phrase"]
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.buttonTapped
[!][<NSThread: 0x600001fee280>{number = 1, name = main}] -- ViewModel.printSomething.onNext -> ["First phrase", "Second phrase", "Third phrase"]