Swift Combine: обрабатывать asyn c на уровне подписки или получать? - PullRequest
0 голосов
/ 03 августа 2020

I wi sh для наблюдения за текущим рядом значений и обработки каждого значения по мере его получения. Обработка значения может вызвать создание и публикацию нового значения. Это является причиной проблем повторного входа.

Исходный код был написан на RxSwift, и проблема повторного входа была решена с помощью асинхронного c планировщика:

eventSubject
    .asObservable()
    .observeOn(MainScheduler.asyncInstance)
    .subscribe(onNext: { [weak self] event in
        self?.handleEvent(event)
    })
    .disposed(by: disposeBag)

Я хотел бы сделать то же самое с Combine, но не понимаю, какие у меня варианты.

enum Event { case foo, bar, baz }

@Published var eventFlow: Event = .foo

...

$eventFlow
    .receive(on: RunLoop.main)
    .sink { [weak self] event in
        DispatchQueue.main.async { [weak self] in
            self?.handleEvent(event)
        }
    }
    .store(in: &cancelBag)

Q. это правильный подход? Требуется ли «receive(on: RunLoop.main)»?

И / или я должен подписываться в очереди, например DispatchQueue.global(), и отказываться от звонка DispatchQueue.main.async?

Любые предложения приветствуются .

1 Ответ

1 голос
/ 03 августа 2020

Нет необходимости в DispatchQueue.main.async, просто передайте DispatchQueue.main в receive(on:), что гарантирует, что все последующие операторы будут выполняться в основном потоке - и, следовательно, ваш sink будет перезванивать в основном потоке. нить тоже.

$eventFlow
    .receive(on: DispatchQueue.main)
    .sink { [weak self] event in
        self?.handleEvent(event)
    }
    .store(in: &cancelBag)
...