如何在主线程中执行 do 运算符的 onSubscribe 操作
How do I execute onSubscribe action of do operator in Main thread
我在do
运算符的onSubscribe
动作中执行了UI相关操作。我得到一个
Main Thread Checker: UI API called on a background thread
Xcode 中的控制台错误。我尝试使用 observe(on: MainScheduler.instance)
但没有成功。
这是我的代码片段:
checkCurrentNetworkAndConnect().observe(on: MainScheduler.instance).do(onSubscribe: {
// UI related stuff
})
我也试过 subscribe(on: MainScheduler.instance)
但没用。
我怎样才能做到这一点?
如果您在后台线程上调用 subscribe
,就会发生这种情况。如果您在后台线程上调用订阅,那么 Observable 将在该后台线程上被订阅。要解决这个问题,您需要在 do
运算符 subscribe(on:)
之后使用 do
...
像这样:
func example() {
checkCurrentNetworkAndConnect()
.do(onSubscribe: {
print("UI related stuff")
})
.subscribe(on: MainScheduler.instance)
.subscribe()
}
通过以上,即使你在后台线程调用example()
,onSubscribe:
闭包也会在主线程上执行。
如果出于某种原因您还希望在后台线程上使用 checkCurrentNetworkAndConnect()
,那么您可以在 do
.
之上使用另一个 subscribe(on:)
来实现
综上所述,您首先不应该在 do(onSubscribe:)
中执行明显的副作用。将调试代码放在那里是一回事,但仅此而已。我已经使用 RxSwift 6 年了,我根本不需要使用 do(onSubscribe:)
,更不用说重要的代码了。可能有更好的方法来实现您要实现的最终目标。
回应您的评论。你如何着手做你想做的事情在很大程度上取决于未提供的细节。下面我做了一些简化的假设。如果您的问题有所不同,我建议您 post 提出一个新问题并提供详细信息...
func example(operations: [Observable<Void>], messages: [String], label: UILabel, disposeBag: DisposeBag) {
Observable.concat(operations.enumerated().map { index, op in
op.map { messages[index + 1] }
})
.startWith(messages[0])
.observe(on: MainScheduler.instance)
.bind(to: label.rx.text)
.disposed(by: disposeBag)
}
以上代码假定:
- 您有一组表示为可观察值的操作
- 其中 none 需要先前操作提供的数据
- 其中 none 发出您希望使用或保留的数据
- 每个操作都有一条消息需要在操作开始前显示
- 最后一个操作完成时会显示一条附加消息
我在do
运算符的onSubscribe
动作中执行了UI相关操作。我得到一个
Main Thread Checker: UI API called on a background thread
Xcode 中的控制台错误。我尝试使用 observe(on: MainScheduler.instance)
但没有成功。
这是我的代码片段:
checkCurrentNetworkAndConnect().observe(on: MainScheduler.instance).do(onSubscribe: {
// UI related stuff
})
我也试过 subscribe(on: MainScheduler.instance)
但没用。
我怎样才能做到这一点?
如果您在后台线程上调用 subscribe
,就会发生这种情况。如果您在后台线程上调用订阅,那么 Observable 将在该后台线程上被订阅。要解决这个问题,您需要在 do
运算符 subscribe(on:)
之后使用 do
...
像这样:
func example() {
checkCurrentNetworkAndConnect()
.do(onSubscribe: {
print("UI related stuff")
})
.subscribe(on: MainScheduler.instance)
.subscribe()
}
通过以上,即使你在后台线程调用example()
,onSubscribe:
闭包也会在主线程上执行。
如果出于某种原因您还希望在后台线程上使用 checkCurrentNetworkAndConnect()
,那么您可以在 do
.
subscribe(on:)
来实现
综上所述,您首先不应该在 do(onSubscribe:)
中执行明显的副作用。将调试代码放在那里是一回事,但仅此而已。我已经使用 RxSwift 6 年了,我根本不需要使用 do(onSubscribe:)
,更不用说重要的代码了。可能有更好的方法来实现您要实现的最终目标。
回应您的评论。你如何着手做你想做的事情在很大程度上取决于未提供的细节。下面我做了一些简化的假设。如果您的问题有所不同,我建议您 post 提出一个新问题并提供详细信息...
func example(operations: [Observable<Void>], messages: [String], label: UILabel, disposeBag: DisposeBag) {
Observable.concat(operations.enumerated().map { index, op in
op.map { messages[index + 1] }
})
.startWith(messages[0])
.observe(on: MainScheduler.instance)
.bind(to: label.rx.text)
.disposed(by: disposeBag)
}
以上代码假定:
- 您有一组表示为可观察值的操作
- 其中 none 需要先前操作提供的数据
- 其中 none 发出您希望使用或保留的数据
- 每个操作都有一条消息需要在操作开始前显示
- 最后一个操作完成时会显示一条附加消息