ReactiveX / RxSwift

Reactive Programming in Swift

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

BehaviorRelay.value not always synchronized with last value pushed using .accept()

Narayane opened this issue · comments

Short description of the issue:

The BehaviorRelay attribute .value is sometimes not correctly updated after the use of .accept()

Expected outcome:

The BehaviorRelay attribute .value should always be equal to last value "pushed" using .accept()

What actually happens:

Sometimes yes, sometimes no, I do not know exactly why

Self contained code example that reproduces the issue:

 ViewModel

  var shouldAlertOnChangesNotSavedValue: Bool { self._shouldAlertOnChangesNotSaved.value }
  var shouldAlertOnChangesNotSaved: Observable<Bool> { self._shouldAlertOnChangesNotSaved.asObservable() }
  private var _shouldAlertOnChangesNotSaved = BehaviorRelay<Bool>(value: false)

   let navigationItemsObservable = self.outputs.navigationItems
            .filterEmpty()
            .map { $0.count }
  
  Observable.combineLatest(navigationItemsObservable, self.navigationController.hasOverviewPendingChanges)
            .do { [weak self] (count, hasPendingChanges) in
                let value = count > 1 && hasPendingChanges
                log.verbose("shouldAlertOnChangesNotSaved: \(value))") // true
                self?._shouldAlertOnChangesNotSaved.accept(value)
            }
            .catchErrorJustComplete()
            .disposed(by: self.disposeBag)

ViewController

  self.viewModel.outputs.shouldAlertOnChangesNotSaved
            .subscribe(onNext: { [weak self] value in
                self?.shouldAlertOnChangesNotSaved = value // false -> true
            })
            .disposed(by: self.disposeBag)

  @objc private func goBack() {
        log.verbose("BehaviorRelay.value: \(self.viewModel.outputs.shouldAlertOnChangesNotSavedValue)") // always false
        log.verbose("Observable.onNext: \(self.shouldAlertOnChangesNotSaved)") // true
        if self.shouldAlertOnChangesNotSaved {
            self.presentBackWithoutSavingAlert()
        } else {
            self.navigationController?.popViewController(animated: true)
        }
    }

RxSwift/RxCocoa/RxBlocking/RxTest version/commit

RxSwift 6.5.0

Platform/Environment

  • iOS
  • macOS
  • tvOS
  • watchOS
  • playgrounds

How easy is to reproduce? (chances of successful reproduce after running the self contained code)

  • easy, 100% repro
  • sometimes, 10%-100%
  • hard, 2% - 10%
  • extremely hard, %0 - 2%

Xcode version:

  14.3.1

Installation method:

  • CocoaPods
  • Carthage
  • Git submodules

I have multiple versions of Xcode installed:
(so we can know if this is a potential cause of your issue)

  • yes (which ones)
  • no

Level of RxSwift knowledge:
(this is so we can understand your level of knowledge
and formulate the response in an appropriate manner)

  • just starting
  • I have a small code base
  • I have a significant code base

Please create a more focused, runnable example of your issue (In an Xcode project)
And share here, so we can check if it's a bug.

Thanks!