RxSwift에서 Relay
와 Subject
의 차이가 무엇일까?
처음에는 Relay와 Subject가 거의 동일하다고 생각했다.
둘 다 이벤트를 전달하고 구독할 수 있기 때문에 크게 다를 게 없어 보였는데 알고보니 다른 점이 꽤나 있었다.
🌳 Subject
- Observable + Observer 역할을 한다.
- 데이터를 방출할 수 있으며, 직접 값을 넣어줄 수 있다.
- 종료(
onCompleted()
) 및 에러(onError()
)를 전달할 수 있다.
- 네트워크 요청이나 비동기 작업에서 유용하다.
Subject 종류
종류 | 초기 값 | 구독 시 전달 값 | 완료 신호 | 에러 전달 | 사용 예제 |
---|
PublishSubject | ❌ | 구독 이후 값 | ✅ | ✅ | 클릭 이벤트, 알림 |
BehaviorSubject | ✅ | 가장 최근 값 | ✅ | ✅ | UI 상태 관리 |
ReplaySubject | ❌ | 지정한 개수만큼 과거 값 | ✅ | ✅ | 로그 기록 |
AsyncSubject | ❌ | 완료 시 마지막 값만 | ✅ | ✅ | 마지막 결과값 |
let subject = PublishSubject<String>()
subject.onNext("A")
subject.subscribe(onNext: { value in
print("Subscriber 1: \(value)")
})
subject.onNext("B")
subject.onNext("C")
🌳 Relay
- Subject와 거의 유사하지만, UI에서 쓰기 좋게 개선된 버전.
- 에러(
onError()
)를 방출하지 않음.
- 완료(
onCompleted()
)되지 않음.
- UI와 데이터 바인딩 시 유용하다.
Relay 종류
종류 | 초기 값 | 구독 시 전달 값 | 완료 신호 | 에러 전달 | 사용 예제 |
---|
PublishRelay | ❌ | 구독 이후 값 | ❌ | ❌ | 버튼 클릭, 이벤트 전달 |
BehaviorRelay | ✅ | 가장 최근 값 | ❌ | ❌ | UI 상태 저장, Form 데이터 |
let relay = PublishRelay<String>()
relay.accept("A")
relay.subscribe(onNext: { value in
print("Subscriber 1: \(value)")
})
relay.accept("B")
relay.accept("C")
Relay vs Subject 차이점 정리
비교 | Subject | Relay |
---|
에러 전달 가능 | ✅ 가능 (onError() ) | ❌ 불가능 |
완료 가능 | ✅ 가능 (onCompleted() ) | ❌ 불가능 |
초기 값 지원 | BehaviorSubject만 지원 | BehaviorRelay 지원 |
UI 바인딩 용도 | ❌ UI에 직접 사용 비효율적 | ✅ UI와 상태 관리에 최적화 |
사용 예시 | 네트워크 요청, 이벤트 스트림 | 버튼 클릭, UI 상태 유지 |
🔥 배운 점
- Subject는 일반적인 이벤트 및 상태 관리에 사용된다.
- 하지만, UI에서는 완료 및 에러 처리가 필요하지 않으므로 사용이 적절하지 않을 수 있다.
- Relay는 UI 상태 및 이벤트 관리에 최적화되어 있다.
- 에러 없이 계속 동작해야 하는 UI 작업(버튼 클릭, 텍스트 입력 등)에 적합하다.
- PublishSubject와 PublishRelay는 이벤트 전달에, BehaviorSubject와 BehaviorRelay는 상태 관리에 적합하다.
- 에러 처리가 필요하면 Subject, UI 상태를 다룰 때는 Relay를 사용하자!