초기값이 없다
구독 이후 전달받은 이벤트부터 반영된다
complete 이후의 이벤트는 반영되지 않는다
func aboutPublishSubject() {
let publish = PublishSubject<Int>()
publish.onNext(20)
publish.onNext(30)
publish
.subscribe(with: self) { owner , value in
print("PublishSubject onNext - \(value)")
} onError: { owner , error in
print("PublishSubject onError - \(error)")
} onCompleted: { owner in
print("PublishSubject onCompleted")
} onDisposed: { owner in
print("PublishSubject onDisposed")
}
.disposed(by: disposeBag)
publish.onNext(3) // 요기부터 반영
publish.onNext(45)
publish.on(.next(9))
publish.onCompleted()
publish.onNext(200)
publish.onNext(500)
}
초기값이 있다 (선언 시 값을 넣어준다)
구독하기 전 가장 마지막 이벤트를 반영한다 (버퍼처럼 가지고 있는다)
complete 이후의 이벤트는 반영되지 않는다
func aboutBehaviorSubject() {
let behavior = BehaviorSubject(value: 100)
behavior.onNext(20)
behavior.onNext(30) // 얘는 요게 찍히네!!
behavior
.subscribe(with: self) { owner , value in
print("BehaviorSubject onNext - \(value)")
} onError: { owner , error in
print("BehaviorSubject onError - \(error)")
} onCompleted: { owner in
print("BehaviorSubject onCompleted")
} onDisposed: { owner in
print("BehaviorSubject onDisposed")
}
.disposed(by: disposeBag)
behavior.onNext(3)
behavior.onNext(45)
behavior.on(.next(9))
behavior.onCompleted()
behavior.onNext(200)
behavior.onNext(500)
}
초기값이 없다
선언 시 버퍼 사이즈를 넣어준다
구독 시점 기준 버퍼 사이즈만큼 이전 이벤트부터 반영된다
complete 이후의 이벤트는 반영되지 않는다
func aboutReplaySubject() {
let replay = ReplaySubject<Int>.create(bufferSize: 3)
replay.onNext(1)
replay.onNext(2)
replay.onNext(3)
replay.onNext(4)
replay.onNext(5) // 요기부터 찍힘!! <- 구독한 시점 기준으로 버퍼 사이즈만큼
replay.onNext(20)
replay.onNext(30)
replay
.subscribe(with: self) { owner , value in
print("ReplaySubject onNext - \(value)")
} onError: { owner , error in
print("ReplaySubject onError - \(error)")
} onCompleted: { owner in
print("ReplaySubject onCompleted")
} onDisposed: { owner in
print("ReplaySubject onDisposed")
}
.disposed(by: disposeBag)
replay.onNext(3)
replay.onNext(45)
replay.on(.next(9))
replay.onCompleted()
replay.onNext(200)
replay.onNext(500)
}
초기값이 없다
구독 전 이벤트는 반영되지 않는다
complete 직전 이벤트 하나만 반영된다
complete 이후의 이벤트는 반영되지 않는다
func aboutAsyncSubject() {
let async = AsyncSubject<Int>()
async.onNext(1)
async.onNext(2)
async.onNext(3)
async.onNext(4)
async.onNext(5)
async.onNext(20)
async.onNext(30)
async
.subscribe(with: self) { owner , value in
print("AsyncSubject onNext - \(value)")
} onError: { owner , error in
print("AsyncSubject onError - \(error)")
} onCompleted: { owner in
print("AsyncSubject onCompleted")
} onDisposed: { owner in
print("AsyncSubject onDisposed")
}
.disposed(by: disposeBag)
async.onNext(3)
async.onNext(45)
async.on(.next(9)) // 요기만 찍힘!
async.onCompleted()
async.onNext(200)
async.onNext(500)
}
let email = emailTextField.rx.text.orEmpty
let password = passwordTextField.rx.text.orEmpty
let validation = Observable.combineLatest(email, password) { first , second in
return first.count > 8 && second.count > 6
}
validation
.bind(to: signInButton.rx.isEnabled)
.disposed(by: disposeBag)
validation
.subscribe(with: self) { owner , value in
owner.signInButton.backgroundColor = value ? UIColor.blue : UIColor.red
owner.emailTextField.layer.borderColor = value ? UIColor.blue.cgColor : UIColor.red.cgColor
owner.passwordTextField.layer.borderColor = value ? UIColor.blue.cgColor : UIColor.red.cgColor
}
.disposed(by: disposeBag)
CombineLatest
는 엮어주는 두 Sequence에 모두 최초 이벤트가 있어야선언할 때 넣어준 초기값부터, onNext
로 전달하는 이벤트들도 잘 반영된다
func testCombineLatest() {
let a = BehaviorSubject(value: 2)
let b = BehaviorSubject(value: "가")
Observable.combineLatest(a, b) { first , second in
return "결과 : \(first) & \(second)"
}
.subscribe(with: self) { owner , value in
print(value)
}
.disposed(by: disposeBag)
a.onNext(100)
a.onNext(200)
a.onNext(300)
b.onNext("감")
b.onNext("남")
b.onNext("담")
}
두 subject 객체에 모두 값이 지정되기 전까지 subscribe가 일어나지 않는다
func testCombineLatest() {
let a = PublishSubject<Int>()
let b = PublishSubject<String>()
Observable.combineLatest(a, b) { first , second in
return "결과 : \(first) & \(second)"
}
.subscribe(with: self) { owner , value in
print(value)
}
.disposed(by: disposeBag)
a.onNext(100)
a.onNext(200)
a.onNext(300)
b.onNext("감")
b.onNext("남")
b.onNext("담")
}
CombineLatest
이벤트가 발생하지 않는다는 건 알겠다.TextField.rx.text.orEmpty
는 초기값을 넣지 않았는데, 왜 이벤트가 잘 실행되었을까?TextField.rx.text.orEmpty
는 초기값이 없는 것이 아니고, 빈 문자열을 이벤트로 전달하기 때문에 정상적으로 combineLatest
이벤트가 실행된다Q. 그럼 RxCocoa에서 제공하는 위와 같은 친구들은 모두 초기값이 있는 거라고 봐도 될까?
A. 그렇지 않더라.
Button.rx.tap
을 두 개 만들어서 똑같이 테스트했는데,combineLatest
이벤트가 발생함을 확인할 수 있었다.
let a = signInButton.rx.tap
let b = signUpButton.rx.tap
let emit = Observable.combineLatest(a, b) { first , second in
print("탭탭 컴바인 레이티스트")
}
emit.subscribe(with: self) { owner , _ in
print("탭탭 섭스크라이브")
}
.disposed(by: disposeBag)