Warm tip: This article is reproduced from serverfault.com, please click

multithreading-如何在后台执行RxSwift?

(multithreading - How to perform RxSwift in the background?)

发布于 2020-12-02 14:16:10

我正在尝试在选择表行时在后台执行复杂的计算,但是它冻结了UI。请查看我的代码,并告诉我可能出了什么问题。

tableView.rx
    .modelSelected(Sring.self)
    .flatMap { item -> Observable<String> in
        
        for _ in 1...2_500 {
            for _ in 1...1_000 {
                
            }
        }
        return Observable.just("Hello world!")

    }
    .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
    .observeOn(MainScheduler.instance)
    .retry()
    .subscribe(onNext: { value in
        print(value)
    })
    .disposed(by: bag)
Questioner
Andrey Isaev
Viewed
11
Daniel T. 2020-12-03 10:24:36

使用此代码首先要了解的是,subscribeOn确定 Observable 事件的事件生成器将在哪个线程上调用,而不是值将在哪个线程上发出。如果源Observable在与其订阅的同一线程上发出,则你的代码将正常工作(例如,如果你使用Observable.just(_:)。但在主线程上modelSelected 发出该信号,而不管其订阅的线程是什么。flatMap运算符在其上调用其闭包)。它的源发出的线程,因此它也在主线程上。

所有这些的结果是,调用几乎没有用subscribeOn(_:)它唯一实际执行预期操作的时间是,如果最终的源(最上游的)是Observable的生成器是同步的,阻塞的函数。(情况并非如此tableView.rx.modelSelected(String.self)

在这种情况下,你想要的更像是:

tableView.rx.modelSelected(String.self)
    .observeOn(ConcurrentDispatchQueueScheduler(qos: .background))
    .flatMap { item -> Observable<String> in
        sleep(3)
        return Observable.just("Hello world!")
    }
    .retry()
    .observeOn(MainScheduler.instance)
    .subscribe(onNext: { value in
        print(value)
    })
    .disposed(by: bag)