ReactiveX / RxSwift

Reactive Programming in Swift
MIT License
24.38k stars 4.17k forks source link

Weird behaviour of share operator on UISegmentedControl observable #2048

Closed jcavar closed 5 years ago

jcavar commented 5 years ago

Short description of the issue:

Using share operator on UISegmentedControl selectedSegmentIndex observable emits duplicated events on subscribe.

Expected outcome:

side effect
1 next(-1)
2 next(-1)

What actually happens:

side effect
1 next(-1)
2 next(-1)
side effect
2 next(-1)

Self contained code example that reproduces the issue:

var bag: DisposeBag? = DisposeBag()

var observable = Observable.just(UISegmentedControl())
    .do(onNext: { _ in
        print("side effect")
    })
    .flatMapLatest { segmented in
        return segmented.rx.selectedSegmentIndex
    }
    .share(replay: 1, scope: .forever)

observable.subscribe { event in
    print("1 \(event)")
}.disposed(by: bag!)

bag = DisposeBag()

observable.subscribe { event in
    print("2 \(event)")
}.disposed(by: bag!)

RxSwift/RxCocoa/RxBlocking/RxTest version/commit

4.3.1

Platform/Environment

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

Xcode version:

10.2.1

:warning: Fields below are optional for general issues or in case those questions aren't related to your issue, but filling them out will increase the chances of getting your issue resolved. :warning:

Installation method:

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

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

freak4pc commented 5 years ago

Hi,

There isn't anything unexpected with your code as far as I can tell. I also don't recommend using .forever for most things. (any reason for this?)

In any sense, this doesn't look like an issue with the project itself but more of a "how do I do XXX" question. Please ask these kinds of questions in our slack channel http://slack.rxswift.org/ or some other more appropriate communication channel.

We are asking this because:

Thank you for understanding.

jcavar commented 5 years ago

How is it expected that the same event is triggered 2 times? Isn't expected behaviour of share operator to replay only latest value(with buffer 1)?

I am using .forever because I want to replay latest value even if all subscribers unsubscribe and then subscribe again.

jcavar commented 5 years ago

Also, I asked this question on Slack channel and other member agrees that this is weird behaviour and that it is worth opening an issue.

freak4pc commented 5 years ago

Hey there - I've answered some of your questions on Slack.

In general .forever isn't guaranteed to do what you want - it can potentially replay stale values, please read the documentation. In general using .forever as if it was a caching mechanism, it's not something you should rely on and as far as I know it's not meant for this.

Note that there are also some minor differences between rebuilding a new DisposeBag vs unsubscribing existing disposables / disposing them.