Swift - RxSwift: Subject와 Relay
Subject는 Observer && Observable
- Observer
- 하나 이상의 Observable을 구독할 수 있음
- 원래 Cold Observable를 Hot Observable로 변경하는 효과 보임
- Hot & Cold
- Observable
- event emit 가능
PublishSubject
- subscribe했을 때 이벤트
- 값이 업데이트될 때마다
- 에러
- subject가 종료 되었을 때
let publishSubject = PublishSubject<Int>() let subscribe1 = publishSubject .subscribe(onNext: { (num) in print("subscribe1 :", num) }, onError: { (error) in print("subscribe1 Erorr: ", error) }, onCompleted: { print("subscribe1 onCompleted") }) publishSubject.onNext(1) publishSubject.onNext(2) let subscribe2 = publishSubject .subscribe(onNext: { (num) in print("subscribe2 :", num) }, onError: { (error) in print("subscribe2 Erorr: ", error) }, onCompleted: { print("subscribe2 onCompleted") }) publishSubject.onNext(3) publishSubject.onCompleted() // 종료 publishSubject.onNext(4) publishSubject.onNext(5)
subscribe1 : 1 subscribe1 : 2 subscribe1 : 3 subscribe2 : 3 subscribe1 onCompleted subscribe2 onCompleted
BehaviorSubject: 초기값이 있는 PublishSubject
-
처음 subscribe하면 초기값 또는 직전의 값 들고 옴
let behaviorSubject = BehaviorSubject<Int>(value: 0) let subscribe1 = behaviorSubject .subscribe(onNext: { (num) in print("subscribe1 :", num) }, onError: { (error) in print("subscribe1 Erorr: ", error) }, onCompleted: { print("subscribe1 onCompleted") }) behaviorSubject.onNext(1) behaviorSubject.onNext(2) let subscribe2 = behaviorSubject .subscribe(onNext: { (num) in print("subscribe2 :", num) }, onError: { (error) in print("subscribe2 Erorr: ", error) }, onCompleted: { print("subscribe2 onCompleted") }) behaviorSubject.onNext(3) behaviorSubject.onCompleted() // 종료 behaviorSubject.onNext(4) behaviorSubject.onNext(5)
subscribe1 : 0 // 초기값 0 subscribe1 : 1 subscribe1 : 2 subscribe2 : 2 // 직전 값 2 subscribe1 : 3 subscribe2 : 3 subscribe1 onCompleted subscribe2 onCompleted
ReplaySubject
-
bufferSize만큼 저장해 두었다가, subscribe하면 저장해 둔 최신 값들 반환
let replaySubject = ReplaySubject<Int>.create(bufferSize: 3) // 모든 이벤트 저장: .createUnbounded() let subscribe1 = replaySubject .subscribe(onNext: { (num) in print("subscribe1 :", num) }, onError: { (error) in print("subscribe1 Erorr: ", error) }, onCompleted: { print("subscribe1 onCompleted") }) replaySubject.onNext(1) replaySubject.onNext(2) let subscribe2 = replaySubject .subscribe(onNext: { (num) in print("subscribe2 :", num) }, onError: { (error) in print("subscribe2 Erorr: ", error) }, onCompleted: { print("subscribe2 onCompleted") }) replaySubject.onNext(3) replaySubject.onCompleted() // 종료 replaySubject.onNext(4) replaySubject.onNext(5)
subscribe1 : 1 subscribe1 : 2 subscribe2 : 1 // 버퍼에 있던 최신값 1 subscribe2 : 2 // 버퍼에 있던 최신값 2 subscribe1 : 3 subscribe2 : 3 subscribe1 onCompleted subscribe2 onCompleted
AsyncSubject
-
complete가 되면 이벤트 발생 후 종료
let asyncSubject = AsyncSubject<Int>() let subscribe1 = asyncSubject .subscribe(onNext: { (num) in print("subscribe1 :", num) }, onError: { (error) in print("subscribe1 Erorr: ", error) }, onCompleted: { print("subscribe1 onCompleted") }) asyncSubject.onNext(1) asyncSubject.onNext(2) let subscribe2 = asyncSubject .subscribe(onNext: { (num) in print("subscribe2 :", num) }, onError: { (error) in print("subscribe2 Erorr: ", error) }, onCompleted: { print("subscribe2 onCompleted") }) asyncSubject.onNext(3) asyncSubject.onCompleted() // 종료 asyncSubject.onNext(4) asyncSubject.onNext(5)
subscribe1 : 3 subscribe2 : 3 subscribe1 onCompleted subscribe2 onCompleted
Relay
PublishRelay
,BehaviorRelay
,ReplayRelay
- RxCocoa의 클래스
-
.accept()
로 이벤트 방출let publishRelay = PublishRelay<Int>() let subscribe = publishRelay.subscribe{ (next) in print("subscribe: ", next.element!) } publishRelay.accept(1) publishRelay.accept(2)
subscribe: 1 subscribe: 2
Subject와 차이
Subject와 2가지 차이점을 빼면 똑같이 동작함
- complete 없음
- error emit 안 함
- 즉 이벤트 보내기만 하고, 종료도 안 됨
- Dispose 전까지 계속 작동하므로 UI Event에서 사용
BehaviorRelay
-
.value
로 현재 값 꺼낼 수 있음let behaviorRelay = BehaviorRelay(value: 0) behaviorRelay.accept(1) let subscribe = behaviorRelay.subscribe{ (next) in print("subscribe: ", next.element!) } behaviorRelay.accept(2) print("value: ", behaviorRelay.value)
subscribe: 1 subscribe: 2 value: 2
음
Publish랑 Behavior 릴레이를 많이 써본 것 같다. 초기값이 필요한 textField와 연동할 때는 Behavior, 네트워크 결과 등 무언가에 대한 결과가 있어야 할 때 등은 Publish 처럼
댓글남기기