繁体   English   中英

RXSwift 没有订阅主线程

[英]RXSwift Not subscribing on Main Thread

我正在尝试进行多次 API 调用并填充 Realm 数据库。 一切正常。 但是,当我尝试在subscribe()方法上运行performSegue()时,会引发异常,通知我不能在后台线程上执行此操作,这是完全合理的。

但是因为我订阅了MainScheduler.instancesubscribe()方法不应该在 UI 线程上运行吗?

Single.zip(APIClient.shared.getSchools(), APIClient.shared.getPointsOfInterest())
        .observeOn(SerialDispatchQueueScheduler(qos: .background))
        .flatMap { zip in return Single.zip(SchoolDao.shared.insertSchools(schoolsJson: zip.0), PointOfInterestDao.shared.insertPointsOfInterest(poisJson: zip.1))}
        .flatMap{ _ in Single.zip(SchoolDao.shared.countSchools(), PointOfInterestDao.shared.countPointsOfInterest())}
        .subscribeOn(MainScheduler.instance)
        .subscribe(onSuccess: { tableCounts in
            let (schoolsCount, poisCount) = tableCounts
            if(schoolsCount != 0 && poisCount != 0){
                print(Thread.isMainThread) //Prints False
                self.performSegue(withIdentifier: "splashToLogin", sender: nil)
            }
        }, onError: {
            error in return
        }).disposed(by: disposeBag)

我是否对 RXSwift 的工作原理做出了错误的假设?

编辑:如果我在.observeOn(MainScheduler.instance) .subscribeOn(MainScheduler.instance)订阅方法在主线程上运行。 这是正确的行为吗? .subscribeOn(MainScheduler.instance)到底在做什么?

您的编辑说明了一切。 您最初对 subscribeOn 和 observeOn 的假设是倒退的。

subscribeOn运算符是指链中运算符上方的可观察对象如何订阅事件源(并且在任何情况下都可能不会按照您的想法进行操作。您的 two.network 调用可能会设置自己的后台线程以发出值,无论它们是如何订阅的。)

例如,看看这个:

extension ObservableType {
    func subscribeOnMain() -> Observable<Element> {
        Observable.create { observer in
            let disposable = SingleAssignmentDisposable()
            DispatchQueue.main.async {
                disposable.setDisposable(self.subscribe(observer))
            }
            return disposable
        }
    }
}

这使得该运算符为何称为 subscribeOn 变得显而易见。 这是因为订阅发生在有问题的调度程序/线程上。 这有助于您更好地理解当您堆叠 subscribeOn 运算符时发生了什么......

observeOn运算符指的是将向观察者发射元素的调度程序(这是传递给subscribe运算符的代码块。)

这看起来像这样:

extension ObservableType {
    func observeOnMain() -> Observable<Element> {
        Observable.create { observer in
            self.subscribe { event in
                DispatchQueue.main.async {
                    observer.on(event)
                }
            }
        }
    }
}

从这里您可以看到订阅是在原始调度程序上进行的,而观察者是在新调度程序上调用的。

这是一篇解释整个事情的好文章: http://rx-marin.com/post/observeon-vs-subscribeon/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM