개발/iOS
[iOS] RxSwift, Subject와 Relay의 차이, 그리고 Publish와 Behavior의 차이
allthi
2024. 11. 13. 14:54
반응형
RxSwift에서 Subject와 Relay의 차이, 그리고 Publish와 Behavior의 차이
1. Subject와 Relay의 차이
- Subject:
- RxSwift에서 Observable과 Observer의 역할을 동시에 수행하는 객체입니다.
- PublishSubject, BehaviorSubject, ReplaySubject, AsyncSubject 등의 타입이 있습니다.
- 기본적으로 종료 이벤트(onCompleted 또는 onError)를 발생시킬 수 있습니다.
- 종료 이벤트 이후에는 새로운 구독자가 들어와도 이벤트를 받지 못합니다.
- Relay:
- RxCocoa에서 제공되며, 종료 이벤트를 발생시키지 않는 Subject의 변형입니다.
- 일반적으로 UI 관련 작업에 많이 사용됩니다.
- PublishRelay와 BehaviorRelay가 있으며, 각각 PublishSubject와 BehaviorSubject와 유사하지만 종료 이벤트 없이 계속 동작합니다.
- UI 이벤트를 관리할 때 불필요한 종료 이벤트를 막아 안정성을 높입니다.
2. Publish와 Behavior의 차이
- PublishSubject / PublishRelay:
- 새로운 구독자가 생기면 구독 이후에 발생하는 이벤트만 수신합니다.
- 구독자가 없을 때 발생한 이벤트는 버려지며, 구독 이후부터 새롭게 발생하는 이벤트만 받을 수 있습니다.
- 예를 들어, UI 버튼을 클릭하는 이벤트와 같이 과거의 상태가 필요하지 않은 경우에 적합합니다.
- BehaviorSubject / BehaviorRelay:
- 구독자가 구독을 시작하면 **가장 최근에 발생한 이벤트(혹은 초기값)**를 즉시 전달받습니다.
- 이후 발생하는 이벤트도 정상적으로 수신합니다.
- 예를 들어, 상태를 지속적으로 유지하고 최신 상태를 즉시 전달받아야 하는 경우에 유용합니다.
요약
- Subject는 종료 이벤트를 발생할 수 있지만, Relay는 종료 이벤트 없이 지속적으로 이벤트를 발행합니다.
- Publish 타입은 구독 이후에 발생하는 이벤트만 전달하는 반면, Behavior 타입은 구독 시점에 최신 상태를 즉시 전달하고 이후 이벤트도 받을 수 있습니다.
코드 예시
Subject 예시
import RxSwift
let subject = PublishSubject<String>()
let disposeBag = DisposeBag()
subject.onNext("A") // 아무도 구독하지 않아 출력되지 않음
subject.subscribe(onNext: { value in
print("Subscriber 1:", value)
}).disposed(by: disposeBag)
subject.onNext("B") // Subscriber 1: B
subject.onNext("C") // Subscriber 1: C
// 새로운 구독자 추가
subject.subscribe(onNext: { value in
print("Subscriber 2:", value)
}).disposed(by: disposeBag)
subject.onNext("D") // Subscriber 1: D, Subscriber 2: D
Relay 예시
import RxSwift
import RxRelay
let relay = PublishRelay<String>()
relay.accept("X") // 아무도 구독하지 않아 출력되지 않음
relay.subscribe(onNext: { value in
print("Relay Subscriber 1:", value)
}).disposed(by: disposeBag)
relay.accept("Y") // Relay Subscriber 1: Y
relay.accept("Z") // Relay Subscriber 1: Z
Publish와 Behavior의 차이
- Publish: 새로운 구독자가 구독할 때 현재 저장된 값이 없고, 구독 후에 방출되는 값만을 받습니다.
- Behavior: 초기값을 설정해야 하며, 구독 시 가장 마지막에 저장된 값을 즉시 전달한 후 새로운 이벤트를 구독자에게 방출합니다.
PublishSubject 예시
let publishSubject = PublishSubject<String>()
publishSubject.onNext("Hello") // 구독자가 없으므로 전달되지 않음
publishSubject.subscribe(onNext: { value in
print("PublishSubject Subscriber:", value)
}).disposed(by: disposeBag)
publishSubject.onNext("World") // PublishSubject Subscriber: World
BehaviorSubject 예시
let behaviorSubject = BehaviorSubject<String>(value: "Initial Value")
behaviorSubject.subscribe(onNext: { value in
print("BehaviorSubject Subscriber 1:", value)
}).disposed(by: disposeBag)
behaviorSubject.onNext("Updated Value") // BehaviorSubject Subscriber 1: Updated Value
behaviorSubject.subscribe(onNext: { value in
print("BehaviorSubject Subscriber 2:", value)
}).disposed(by: disposeBag)
// 새로운 구독자에게 마지막 값 전달
// BehaviorSubject Subscriber 2: Updated Value
이처럼 Subject와 Relay, Publish와 Behavior는 RxSwift에서 데이터 스트림의 특성에 따라 다르게 활용됩니다.
반응형