RxSwift —不冻结UI的后台任务

dob*_*noc 5 multithreading ios swift rx-swift

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

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

为什么上述方法无法按预期工作,以及如何使其正常工作?

Max*_*gin 5

我相信问题在于您对.heavyLiftingFuncReturningObservable()的实现,即事实上,它显然开始在当前线程上工作,而不是等到订阅并在后台调度程序上运行后才开始。解决方案是在.heavyLiftingFuncReturningObservable()函数内部使用.deferred()

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


Sof*_*ner 5

你可以这样做:

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