RxSwift 中的网络请求调度器

Adr*_*ias 6 multithreading ios swift rx-swift

从一开始,我就一直在学习 Rxswift 并将其应用到一个项目中。我希望你的帮助对一个概念更加放心。

我了解 UI 中的更改应该在 Mainscheduler 上执行.observeOn(MainSchedule…,如果您不使用Drivers.

我的疑问是:通常,我应该在执行网络请求时显式切换到后台线程吗?.

我还没有找到很多关于这一点的文献,但我已经阅读了一些项目代码,其中大多数没有,但有一些是。那些最终使用Drivers.observeOn(MainSchedule…在 UI 上进行更改。

例如,在https://www.thedroidsonroids.com/blog/rxswift-examples-4-multithreading 中,他说

So as you may guessed, in fact everything we did was done on a MainScheduler. Why? Because our chain starts from searchBar.rx_text and this one is guaranteed to be on MainScheduler. And because everything else is by default on current scheduler – well our UI thread may get overwhelmed. How to prevent that? Switch to the background thread before the request and before the mapping, so we will just update UI on the main thread

所以他为解决他提到的问题所做的,就是明确声明 .observeOn(ConcurrentDispatchQueueScheduler(globalConcurrentQueueQOS: .Background))

假设 API 请求无论如何都会在后台执行,这样做的作用是在后台执行所有其他计算,对吗?

这是一个好习惯吗?我是否应该在每个 API 请求中明确更改为后台,然后仅在必要时更改回 Main?

如果是这样,最好的方法是什么?观察背景,然后在主要?或者在后台订阅并在 Main 上观察,就像在这个要点中所做的那样:https : //gist.github.com/darrensapalo/711d33b3e7f59b712ea3b6d5406952a4

或者也许是另一种方式?

PS:抱歉旧代码,但在我找到的链接中,这些更适合我的问题。

Max*_*gin 4

Normally, i.e. if you do not specify any schedulers, Rx is synchronous.

\n\n

其余的实际上取决于您的用例。第四个例子,所有 UI 操作都必须发生在主线程调度程序上。

\n\n

后台工作(包括网络请求)应在后台调度程序上运行。哪些 - 取决于并发/串行执行的优先级和偏好。

\n\n

.subscribeOn()定义工作在哪里完成以及.observeOn() defines where the results of it are handled.

\n\n

因此,您的具体问题的答案:如果网络调用的结果将反映在 UI 中,您必须订阅后台调度程序并观察 on main.

\n\n

您可以这样声明调度程序(仅作为示例):

\n\n
static let main = MainScheduler.instance\nstatic let concurrentMain = ConcurrentMainScheduler.instance\n\nstatic let serialBackground = SerialDispatchQueueScheduler.init(qos: .background)\nstatic let concurrentBackground = ConcurrentDispatchQueueScheduler.init(qos: .background)\n\nstatic let serialUtility = SerialDispatchQueueScheduler.init(qos: .utility)\nstatic let concurrentUtility = ConcurrentDispatchQueueScheduler.init(qos: .utility)\n\nstatic let serialUser = SerialDispatchQueueScheduler.init(qos: .userInitiated)\nstatic let concurrentUser = ConcurrentDispatchQueueScheduler.init(qos: .userInitiated)\n\nstatic let serialInteractive = SerialDispatchQueueScheduler.init(qos: .userInteractive)\nstatic let concurrentInteractive = ConcurrentDispatchQueueScheduler.init(qos: .userInteractive)\n
Run Code Online (Sandbox Code Playgroud)\n\n

PS 一些第 3 方库可能提供预先配置为在后台调度程序上执行的可观察对象。在这种情况下,.subscribeOn()不需要显式调用。但您需要确定情况是否如此。

\n\n

回顾一下:

\n\n
    \n
  • 通常,在执行网络请求时我应该显式切换到后台线程吗?- 是的,除非图书馆为你做

  • \n
  • 我是否应该在每个 API 请求中显式更改为后台,然后仅在必要时更改回 Main?- 是的

  • \n
  • 如果是这样,最好的方法是什么?\xc2\xa0[...]在后台订阅并在 Main 上观察

  • \n
\n