Last active
August 7, 2021 08:52
-
-
Save fishkingsin/0bf53f4d285e090cf576696defcf9ef0 to your computer and use it in GitHub Desktop.
ChildProblem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import RxSwift | |
import RxCocoa | |
//func ignoreNil<A>(x: A?) -> Observable<A> { | |
// return x.map { Observable.just($0) } ?? Observable.empty() | |
//} | |
func ignoreNil<A>(x: A?) -> Driver<A> { | |
return x.map { Driver.just($0) } ?? Driver.empty() | |
} | |
public protocol OptionalType { | |
associatedtype Wrapped | |
var optional: Wrapped? { get } | |
} | |
extension Optional: OptionalType { | |
public var optional: Wrapped? { return self } | |
} | |
// Unfortunately the extra type annotations are required, otherwise the compiler gives an incomprehensible error. | |
extension Observable where Element: OptionalType { | |
func ignoreNil() -> Observable<Element.Wrapped> { | |
return flatMap { value in | |
value.optional.map { Observable<Element.Wrapped>.just($0) } ?? Observable<Element.Wrapped>.empty() | |
} | |
} | |
} | |
class Parent { | |
let bag = DisposeBag() | |
let streamA: BehaviorRelay<String?> = BehaviorRelay(value: nil) | |
let streamB: BehaviorRelay<String?> = BehaviorRelay(value: nil) | |
let dummyStream: BehaviorRelay<String?> = BehaviorRelay(value: nil) | |
let moduleVisibility: BehaviorRelay<Bool?> = BehaviorRelay(value: nil) | |
var combineStream: Driver<(String?, String?, String?)> { | |
Driver | |
.combineLatest( | |
streamA.asDriver(), | |
streamB.asDriver(), | |
dummyStream.asDriver() | |
) | |
} | |
var combineStream2: Driver<(String?, String?)> { | |
Driver | |
.combineLatest( | |
streamA.asDriver(), | |
streamB.asDriver() | |
) | |
} | |
init() { | |
BehaviorRelay | |
.combineLatest( | |
streamA.flatMap(ignoreNil).distinctUntilChanged(), | |
streamB.flatMap(ignoreNil).distinctUntilChanged(), | |
dummyStream.flatMap(ignoreNil).distinctUntilChanged() | |
).subscribe (onNext: {[weak self ] a, b, c in | |
guard let self = self else { return } | |
print("moduleVisibility ") | |
self.moduleVisibility.accept(true) | |
}).disposed(by: bag) | |
} | |
} | |
class Child: Parent { | |
override init() { | |
super.init() | |
moduleVisibility | |
.asDriver() | |
.flatMap(ignoreNil) | |
.asObservable() | |
.filter({ $0 == true}) | |
.subscribe( onNext: { moduleVisibility in | |
print("moduleVisibility \(moduleVisibility)") | |
}).disposed(by: bag) | |
moduleVisibility | |
.asDriver() | |
.flatMap(ignoreNil) | |
.asObservable() | |
.filter({ $0 == true}) | |
.withLatestFrom( | |
combineStream | |
.asObservable(), | |
resultSelector: { upStream, downStream in | |
downStream | |
} | |
) | |
.subscribe(onNext: { valueA, valueB, valueC in | |
// This line does not get called | |
print("combineStream \(valueA) \(valueB) \(valueC)") | |
}).disposed(by: bag) | |
moduleVisibility | |
.asDriver() | |
.flatMap(ignoreNil) | |
.asObservable() | |
.filter({ $0 == true}) | |
.withLatestFrom( | |
combineStream2 | |
.asObservable() | |
) | |
.subscribe(onNext: { valueA, valueB in | |
// This line does not get called | |
print("combineStream2 \(valueA) \(valueB)") | |
}).disposed(by: bag) | |
} | |
} | |
var child: Child? = Child() | |
child?.streamA.accept("A") | |
child?.streamB.accept("B") | |
child?.dummyStream.accept("C") | |
child = nil | |
child = Child() | |
child?.streamB.accept("B") | |
child?.streamA.accept("A") | |
child?.dummyStream.accept("C") | |
/* | |
moduleVisibility | |
moduleVisibility true | |
combineStream Optional("A") Optional("B") nil | |
combineStream2 Optional("A") Optional("B") | |
moduleVisibility | |
moduleVisibility true | |
combineStream Optional("A") Optional("B") nil | |
combineStream2 Optional("A") Optional("B") | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment