#multithreading #concurrency #grand-central-dispatch #rx-swift
#многопоточность #параллелизм #grand-central-dispatch #rx-быстрый
Вопрос:
Я пытаюсь выполнить сложное вычисление в фоновом режиме при выборе строки таблицы, но это замораживает пользовательский интерфейс. Пожалуйста, взгляните на мой код и скажите мне, что может быть не так.
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)
Ответ №1:
Первое, что нужно понять с помощью этого кода, — это то, что subscribeOn
определяет, в каком потоке будет вызываться генератор событий наблюдаемого, а не в каком потоке будут передаваться значения. Если исходный наблюдаемый объект генерируется в том же потоке, на который он подписан, тогда ваш код сработал бы (например, если бы вы использовали Observable.just(_:)
. Но modelSelected
генерируется в основном потоке, независимо от того, на какой поток он был подписан. flatMap
Оператор вызывает свое закрытие в потоке, в котором испускается его источник, так что он также находится в основном потоке.
Результатом всего этого является то , что звонить редко бывает полезно subscribeOn(_:)
. Единственный раз, когда он действительно делает то, что вы ожидаете, — это если конечный источник (самый восходящий) Наблюдаемого генератора является синхронной блокирующей функцией. (Чего нельзя сказать о случае с 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)
Комментарии:
1. Большое вам спасибо за ваше любезное объяснение. Все работает так же, как в вашем коде выше.