首页 > 解决方案 > RXSwift 未订阅主线程

问题描述

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

但既然我订阅了MainScheduler.instance该方法不应该subscribe()在 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)甚至在做什么?

标签: iosswiftrx-swift

解决方案


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

操作员指的subscribeOn是链中的第一个可观察对象如何订阅事件的最终源(并且在任何情况下都可能不会做你认为它会做的事情。你的两个网络调用可能会设置自己的后台线程来发出值不管他们是如何订阅的。)

observeOn操作员是指将向观察者发出元素的调度程序(这是传递给操作员的代码块。subscribe

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


推荐阅读