将 PublishRelay 转换为可选元素的行为中继



我在基于 RxSwift 4.0 的项目中有以下代码:

private var _myRelay = PublishRelay<MyData>()
var myRelay: Observable<MyData> {
return _myRelay.asObservable()
}

现在我需要将最后一个值(如果有的话(保留在_myRelay中,所以我决定将其转换为BehaviorRelay

private var _myRelay = BehaviorRelay<MyData?>(value: nil)

我想保持公共接口完整

var myRelay: Observable<MyData>

我的意思是我不想将其转换为

var myRelay: Observable<MyData?>

这个想法不是"发布"初始值==nilmyRelay的订阅者,并且仅在某些数据出现后才开始发布。我该怎么做?我是Rx的完全初学者,但我相信应该有一些优雅的解决方案。

最简单的解决方案是过滤掉 nils。如果您使用的是 5.0,那么您将使用compactMap执行此操作,但既然您说 4.0,这意味着您将需要一个过滤器和地图:

var myRelay: Observable<MyData> {
return _myRelay.filter { $0 != nil }.map { $0! }.asObservable()
}

但实际上,使用ReplaySubject而不是中继可能会更好。

private let _myRelay = ReplaySubject<MyData>.create(bufferSize: 1)
var myRelay: Observable<MyData> {
return _myRelay.asObservable()
}

这样,您根本不需要处理 nils。(另请注意,_myRelay应该是let而不是变量。

执行上述操作还将允许您在可观察量超出范围时发出completed事件(中继不允许这样做(。

private let _myRelay = ReplaySubject<MyData>.create(bufferSize: 1)
var myRelay: Observable<MyData> {
return _myRelay.asObservable()
}
deinit {
_myRelay.onCompleted()
}

最新更新