BehaviorSubject
https://codeisfuture.tistory.com/125
RxSwift(2)-Subject
1. Subject란?RxSwift에서 Subject는 Observable과 Observer의 특성을 모두 갖춘 하이브리드 요소입니다. Observable처럼 값을 방출할 수 있으며, 동시에 Observer처럼 다른 Observable을 구독할 수도 있습니다.흠...
codeisfuture.tistory.com
를 기억하시는가??? 아주 초반에 공부했던것이다. combine의 CurrentValueSubject와 비슷한 것으로 초기값을 가지고 구독시 최신 값을 즉시 수신하고 onNext, onError, onCompleted호출이 가능했다.
BehaviorRelay
BehaviorRelay는 RxCocoa 프레임워크에서 제공하는 특별한 Observable 타입으로, BehaviorSubject를 래핑한 클래스입니다. BehaviorRelay는 다음과 같은 특징을 갖습니다:
1.초기값 필수: 생성 시 반드시 초기값을 제공해야 합니다.
2. 현재값 저장: 가장 최근에 방출된 값을 저장하고 새 구독자에게 즉시 제공합니다.
3. 값 접근 가능: value 속성을 통해 현재 값에 직접 접근할 수 있습니다.
4. 에러방출 없음: 에러가 방출하지않으며, 항상 값만 전달합ㄴ디ㅏ.
5. 종료없음: complted이벤트를 방출하지 않으므로 영원히 활성상태 유지
결국 BehaviorSubject와 달리 onNext, onError, onCompleted 메서드 대신 accept만 사용해 새 값을 전달한다는 것입니다.
이러한 차이점때문에 특히 UI상태와 같이에러나 완료 이벤트 없이 계속해서 업뎃해야하는 데이터 흐름에 적합합니다. MVVM패턴을 사용할때 ViewModel의 데이터 바인딩에 적합할 것 같습니다.
BehaviorSubject vs BehaviorRelay: 자세한 비교
BehaviorRelay와 BehaviorSubject는 서로 밀접하게 관련되어 있지만, 용도와 특성에 차이가 있습니다.
공통점
- 둘 다 초기값을 가집니다
- 가장 최근 값을 새 구독자에게 즉시 제공합니다
- 상태(state)를 저장하고 관리하는 용도로 사용됩니다
차이점
특성BehaviorSubjectBehaviorRelay
값 추가 메서드 | onNext() | accept() |
에러 발생 | onError() 가능 | 불가능 |
완료 | onCompleted() 가능 | 불가능 |
현재값 접근 | value() 함수 (throws) | value 프로퍼티 (direct) |
주요 용도 | 일반적인 반응형 프로그래밍 | UI 상태 관리 |
예를 들어, UI 상태 관리 위주 - BehaviorRelay상태 변경 감지가 필요하지만, 에러 및 완료 이벤트는 불필요 - BehaviorRelay특정 시점에 Subject 종료되어야함 - BehaviorSubjectObservable이 에러를 방출해야함 - BehaviorSubject
Driver
우리는 이전에 Driver또한 UI바인딩을 안전하게 수행하는데 사용했습니다. 대체로 BehaviorRelay는 Driver와 함께 사용하여 UI상태를 더욱 안전하게 관리합니다.
Driver가 UI바인딩이 목적이라면 BehaviorRelay는 상태 저장 및 관리입니다.
class ProfileViewModel {
// 1. 상태 저장 (BehaviorRelay)
private let nameRelay = BehaviorRelay<String>(value: "")
private let ageRelay = BehaviorRelay<Int>(value: 0)
// 2. UI 바인딩용 Driver 제공
var name: Driver<String> {
return nameRelay.asDriver()
}
var age: Driver<Int> {
return ageRelay.asDriver()
}
// 3. 상태 변경 메서드
func updateProfile(name: String, age: Int) {
nameRelay.accept(name)
ageRelay.accept(age)
}
}
1. 명확한 책임 분리
- BehaviorRelay: 내부 상태 저장 및 변경 (ViewModel 내부)
- Driver: UI 바인딩에 최적화된 읽기 전용 스트림 (ViewModel → View)
2. 상태 변경의 용이성
- Driver는 값의 변경이 불가능합니다(읽기 전용). 새 상태를 만들려면 기존 Driver에 새 스트림을 결합해야 합니다.
- BehaviorRelay는 accept() 메서드로 간단히 상태를 변경할 수 있습니다.
3. 메모리 및 성능 최적화
- BehaviorRelay: 값을 저장하므로 메모리 사용
- Driver: 스트림 최적화 (메인 스레드 실행, 에러 제거, 리소스 공유)
- 두 가지를 적절히 조합하면 메모리와 성능 사이의 균형을 찾을 수 있습니다
User Input → BehaviorRelay(상태 변경) → asDriver() → UI 바인딩
예씨
class ProfileViewModel {
// 1. 상태 저장용 BehaviorRelay
private let nameRelay = BehaviorRelay<String>(value: "")
private let ageRelay = BehaviorRelay<Int>(value: 0)
// 2. UI 바인딩용 Driver
var name: Driver<String> {
nameRelay.asDriver()
}
var age: Driver<Int> {
ageRelay.asDriver()
}
// 3. 파생 상태 계산 (name이 비어있지 않고 age가 18 이상일 때)
var isSaveButtonEnabled: Driver<Bool> {
Observable.combineLatest(nameRelay, ageRelay)
.map { name, age in
!name.isEmpty && age >= 18
}
.asDriver(onErrorJustReturn: false)
}
// 4. 상태 업데이트 메서드
func updateProfile(name: String, age: Int) {
nameRelay.accept(name)
ageRelay.accept(age)
}
}
// TextField 입력을 ViewModel에 바인딩
nameTextField.rx.text.orEmpty
.subscribe(onNext: { [weak self] text in
guard let self = self else { return }
let currentAge = Int(self.ageTextField.text ?? "0") ?? 0
self.viewModel.updateProfile(name: text, age: currentAge)
})
.disposed(by: disposeBag)
// ViewModel의 Driver를 UI에 바인딩
viewModel.name
.drive(nameTextField.rx.text)
.disposed(by: disposeBag)
viewModel.isSaveButtonEnabled
.drive(saveButton.rx.isEnabled)
.disposed(by: disposeBag)
- BehaviorRelay(상태 저장):
- nameRelay와 ageRelay는 현재 사용자 정보를 저장
- accept() 메서드로 값을 쉽게 업데이트
- ViewModel 내부에서만 접근 가능(private)
- Driver(UI 바인딩):
- name, age, isSaveButtonEnabled 프로퍼티가 UI 바인딩용 스트림 제공
- 메인 스레드에서 실행 보장
- 에러가 발생하지 않음
- 리소스 효율적 공유
데이터 흐름:
사용자 입력 → BehaviorRelay(상태 저장) → asDriver() → UI 컴포넌트
참고자료
https://green1229.tistory.com/546
RxSwift - BehaviorSubject vs BehaviorRelay
안녕하세요. 그린입니다 🍏이번 포스팅은 RxSwift에서 BehaviorSubject와 BehaviorRelay의 차이에 대해 학습해보겠습니다 🙋🏻 RxSwift를 사용하여 상태를 관리할 때 두 개념 모두 자주 사용되는데요.두
green1229.tistory.com
https://green1229.tistory.com/547
RxSwift/RxCocoa - Driver & BehaviorRelay
안녕하세요. 그린입니다 🍏이번 포스팅에서는 Driver와 BehaviorRelay에 대해 알아보며 연관 관계에 대해 정리해보겠습니다 🙋🏻 그전에, BehaviorRelay에 대해 알고 있는것이 더 편리해요. RxSwift -
green1229.tistory.com
'반응형프로그래밍' 카테고리의 다른 글
RxSwift(9) - Scheduler (0) | 2025.05.09 |
---|---|
RxSwift(8)-에러처리 (0) | 2025.05.08 |
RxSwift(6)-RxCocoa(bind, drive, DelegateProxy) (0) | 2025.05.06 |
RxSwift(5)-TimeBasedOperators (0) | 2025.05.04 |
RxSwift(4)-Combining Operators (0) | 2025.05.02 |