RxSwiftでwithLatestFromが最新じゃなくなることがあるorz

Observable①でwithLatestFromをしてObservable②を取り込むとします。
Observable①の上流でObservable②がトリガーだった場合に、想定しいない値が入ってくる場合があります。

## 想定している最新値が取得できない実装

下記のような実装があるとします。

1. selectedUserの値が更新され、その値がnilでなかった場合にshowUserでvoidを流す
2. showUserに値が流れたら、withLatestFromで最新のselectedUserを取得
3. withLatetFromで取得したselectedUserをprint

```swift:ソース①
let selectedUser = Variable<String?>(nil)
let showUser = PublishSubject<Void>()

_ = selectedUser.asObservable()
    .filter { $0 != nil }
    .debug("selectedUser")
    .subscribe(onNext: { _ in
        showUser.onNext()
    })

_ = showUser
    .withLatestFrom(selectedUser.asObservable().debug("withLatestFrom.selectedUser"))
    .debug("showUser")
    .subscribe(onNext: { user in
        print("print user = ", user)
    })

print("set tatusmi")
selectedUser.value = "tatsumi"
```

さて、上記の実装の場合、どのようなものがprintで表示されるでしょうか。
showUserのトリガーがnilではないselectedUserになっているので、`print user = tatsumi`になることを想定しています。
しかしながら、実際には**print user = nil**となります。
showUserのトリガーがselectedUserに値が流れてnil出ないことを確認しているにも関わらず、withLatestFromで取得したselectedUserがnilになってしまっています。

デバッグログは下記のようになります。

```
2017-08-24 14:51:32.339: selectedUser -> subscribed
2017-08-24 14:51:32.342: showUser -> subscribed
2017-08-24 14:51:32.342: withLatestFrom.selectedUser -> subscribed
2017-08-24 14:51:32.342: withLatestFrom.selectedUser -> Event next(nil)
set tatusmi
2017-08-24 14:51:32.343: selectedUser -> Event next(Optional("tatsumi"))
2017-08-24 14:51:32.343: showUser -> Event next(nil)
print user =  nil
2017-08-24 14:51:32.343: withLatestFrom.selectedUser -> Event next(Optional("tatsumi"))
2017-08-24 14:51:32.344: selectedUser -> Event completed
2017-08-24 14:51:32.344: selectedUser -> isDisposed
2017-08-24 14:51:32.344: withLatestFrom.selectedUser -> Event completed
2017-08-24 14:51:32.344: withLatestFrom.selectedUser -> isDisposed
```

ソース①では

1. selectedUser
2. showUser
3. withLatestFrom.selectedUser

という順番にsubscribeされています。

subscribe後は

1. withLatestFrom.selectedUserの直後にwithLatestFrom.selectedUserで初期値のnilをキャッシュ
2. selectedUserにtatsumiが流れてくる
3. showUserに値が流れてくる
4. printを実行
5. withLatestFrom.selectedUserにtatsumiが流れてくる

という流れで実行されます。



## 想定している最新値が取得できる実装①

それでは、showUserを間に挟まない実装をした場合はどうでしょうか。

```swift:ソース②
let selectedUser = Variable<String?>(nil)

_ = selectedUser.asObservable()
    .withLatestFrom(selectedUser.asObservable().debug("withLatestFrom.selectedUser"))
    .filter { $0 != nil }
    .debug("selectedUser")
    .subscribe(onNext: { user in
        print("print user = ", user)
    })

print("set tatusmi")
selectedUser.value = "tatsumi"
```

実行結果は**print user = tatsumi**となります。

```
2017-08-24 14:52:02.103: selectedUser -> subscribed
2017-08-24 14:52:02.103: withLatestFrom.selectedUser -> subscribed
2017-08-24 14:52:02.104: withLatestFrom.selectedUser -> Event next(nil)
set tatusmi
2017-08-24 14:52:02.105: withLatestFrom.selectedUser -> Event next(Optional("tatsumi"))
2017-08-24 14:52:02.105: selectedUser -> Event next(Optional("tatsumi"))
print user =  Optional("tatsumi")
2017-08-24 14:52:02.106: withLatestFrom.selectedUser -> Event completed
2017-08-24 14:52:02.106: withLatestFrom.selectedUser -> isDisposed
2017-08-24 14:52:02.106: selectedUser -> Event completed
2017-08-24 14:52:02.107: selectedUser -> isDisposed
```

ソース②では

1. selectedUser
2. withLatestFromのselectedUser

という順番にsubscribeされています。

subscribe後は

1. withLatestFrom.selectedUserの直後にwithLatestFrom.selectedUserで初期値のnilをキャッシュ
2. withLatestFrom.selectedUserにtatsumiが流れてくる
3. selectedUserにtatsumiが流れてくる
4. showUserに値が流れてくる
5. printを実行

という流れで実行されます。

## 想定している最新値が取得できる実装②

```swift:ソース③
let selectedUser = Variable<String?>(nil)
let showUser = PublishSubject<Void>()

_ = showUser
    .withLatestFrom(selectedUser.asObservable().debug("withLatestFrom.selectedUser"))
    .debug("showUser")
    .subscribe(onNext: { user in
        print("print user = ", user)
    })

_ = selectedUser.asObservable()
    .filter { $0 != nil }
    .debug("selectedUser")
    .subscribe(onNext: { _ in
        showUser.onNext()
    })

print("set tatusmi")
selectedUser.value = "tatsumi"
```

実行結果は**print user = tatsumi**となります。

```
2017-08-24 14:50:42.238: showUser -> subscribed
2017-08-24 14:50:42.239: withLatestFrom.selectedUser -> subscribed
2017-08-24 14:50:42.239: withLatestFrom.selectedUser -> Event next(nil)
2017-08-24 14:50:42.241: selectedUser -> subscribed
set tatusmi
2017-08-24 14:50:42.242: withLatestFrom.selectedUser -> Event next(Optional("tatsumi"))
2017-08-24 14:50:42.242: selectedUser -> Event next(Optional("tatsumi"))
2017-08-24 14:50:42.242: showUser -> Event next(Optional("tatsumi"))
print user =  Optional("tatsumi")
2017-08-24 14:50:42.243: withLatestFrom.selectedUser -> Event completed
2017-08-24 14:50:42.243: withLatestFrom.selectedUser -> isDisposed
2017-08-24 14:50:42.243: selectedUser -> Event completed
2017-08-24 14:50:42.243: selectedUser -> isDisposed
```

ソース③では

1. showUser
2. withLatestFromのselectedUser
3. selectedUser

という順番にsubscribeされています。

subscribe後は

1. withLatestFrom.selectedUserのsubscribe直後にwithLatestFrom.selectedUserで初期値のnilをキャッシュ
2. withLatestFrom.selectedUserにtatsumiが流れてくる
3. selectedUserにtatsumiが流れてくる
4. showUserに値が流れてくる
5. printを実行

という流れで実行されます。

## その他の実装

withLatestFromではなく、flatMapでselectedUserを都度取り込みます。

```swift:ソース④
let selectedUser = Variable<String?>(nil)
let showUser = PublishSubject<Void>()

_ = selectedUser.asObservable()
    .filter { $0 != nil }
    .debug("selectedUser")
    .subscribe(onNext: { _ in
        showUser.onNext()
    })

_ = showUser
    .flatMap { selectedUser.asObservable().debug("withLatestFrom.selectedUser") }
    .debug("showUser")
    .subscribe(onNext: { user in
       print("print user = ", user)
    })

print("set tatusmi")
selectedUser.value = "tatsumi"
```

```
2017-08-24 15:16:57.120: selectedUser -> subscribed
2017-08-24 15:16:57.122: showUser -> subscribed
set tatusmi
2017-08-24 15:16:57.123: selectedUser -> Event next(Optional("tatsumi"))
2017-08-24 15:16:57.124: withLatestFrom.selectedUser -> subscribed
2017-08-24 15:16:57.124: withLatestFrom.selectedUser -> Event next(Optional("tatsumi"))
2017-08-24 15:16:57.124: showUser -> Event next(Optional("tatsumi"))
print user =  Optional("tatsumi")
```

## 最後に
RxSwiftのissueにも似たようなものがありました。
[withLatestFrom doesn't actually provide latest value #1121](https://github.com/ReactiveX/RxSwift/issues/1121)