RxSwift - 没有冻结UI的后台任务

时间:2017-11-09 12:55:11

标签: ios swift multithreading rx-swift

我想在我的iOS应用程序的后台线程中做一些繁重的工作,而不是在执行时冻结UI。我尝试的是:

self.someDisposable = heavyLiftingFuncReturningObservable()
            .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
            .observeOn(MainScheduler.instance)
            .subscribe(
                onNext: { [weak self] image in
                    // update UI
                },
                onError: { ... }
            )

为什么上述内容无法正常工作以及如何使其正常工作?

3 个答案:

答案 0 :(得分:4)

我认为问题在于你的 .heavyLiftingFuncReturningObservable()的实现,即显然它开始在当前线程上工作而不是等到订阅并在后台调度程序上运行。解决方法是在 .heavyLiftingFuncReturningObservable()函数中使用 .deferred()

请参阅http://adamborek.com/top-7-rxswift-mistakes/

答案 1 :(得分:1)

您可以这样做:

self.someDisposable = Observable.just(0) // dummy
    .observeOn(ConcurrentDispatchQueueScheduler(qos: .background))
    .flatMap { [unowned self] _ in
        heavyLiftingFuncReturningObservable()
    }
    .subscribeOn(MainScheduler.instance)
    .subscribe(
        onNext: { [weak self] image in
            // update UI
        },
        onError: { ... }
    )

答案 2 :(得分:0)

不要这样做...使用Observable.deferred { }方法

将繁重的任务放在块中,它将在订阅时运行。

如果作品只有一个响应,请使用 Single 可观察类型。
如果工作只需完成,请使用 Completable 可观察类型

使用 observeOn / subscribleOn 运算符来控制执行工作的线程。

最重要的是,不要在这个用例中使用 RX。