개발콩블로그
[RxSwift] PublishSubject, BehaviorSubject, ReplaySubject, AsyncSubject 본문
RxSwift
[RxSwift] PublishSubject, BehaviorSubject, ReplaySubject, AsyncSubject
devBean 2025. 2. 26. 23:56안녕하세요 개발콩입니다!
RxSwift는 사용하는 것도 중요하지만 잘 알고 적절하게 사용하는 것이 중요한 것 같습니다.
오늘은 Subject에 대해서 알아보도록 하겠습니다.
Subject
- 이벤트 방출하는 Observable의 역할을 수행할 수 있습니다.
- 이벤트를 받고 처리하는 Observer의 역할을 수행할 수 있습니다.
Subject의 종류에는 4가지가 있습니다.
- PublishSubject
- BehaviorSubject
- ReplaySubject
- AsyncSubject
4가지의 Subject에 대해서 알아보도록 하겠습니다.
PublishSubject
- 초기값이 없습니다.
- 구독 이후의 시점부터 방출되는 이벤트를 처리할 수 있습니다.
let publishSubject = PublishSubject<String>()
publishSubject
.subscribe { eventString in
print("onNext - \(eventString)")
} onError: { error in
print("onError - \(error)")
} onCompleted: {
print("onComplete")
} onDisposed: {
print("onDisposed")
}
.disposed(by: disposeBag)
이벤트가 방출되었을 때 처리하는 이벤트를 정의했습니다.
아래의 이벤트를 보내보도록 하겠습니다.
publishSubject.onNext("안녕하세요") // onNext - 안녕하세요
publishSubject.onCompleted() // onComplete, onDisposed
publishSubject.onNext("반가워요") // 출력 X
구독시점 이후에 onNext method를 사용해서 이벤트를 방출할 수 있습니다.
여기서 중요한 것은 complete된 이후에 onDisposed가 동작하고 그 이후에는 값을 방출하지 않습니다.
publishSubject.onNext("안녕하세요") // onNext - 안녕하세요
publishSubject.onError(SampleError.error) // onError - error, onDisposed
publishSubject.onNext("반가워요") // 출력 X
이것은 Error가 방출되고 나서 onDisposed가 동작하고 그 이후에는 값을 방출하지 않고 stream이 끊어진 것을 확인할 수 있었습니다.
다른 Observable의 생명주기도 위와 같습니다.
BehaviorSubject
- 초기값이 존재합니다.
- 구독 시점에 가장 최근에 방출된 이벤트를 처리합니다.
- 최근에 방출된 이벤트가 없다면 초기값을 처리할 수 있습니다. (초기값이 필요한 이유입니다)
let behaviorSubject = BehaviorSubject(value: "첫 인사말로 반가워요!")
behaviorSubject
.subscribe { eventString in
print("onNext - \(eventString)")
} onError: { error in
print("onError - \(error)")
} onCompleted: {
print("onComplete")
} onDisposed: {
print("onDisposed")
}
.disposed(by: disposeBag)
// onNext - 첫 인사말로 반가워요!
behaviorSubject.onNext("안녕하세요") // onNext - 안녕하세요
구독과 동시에 "첫 인사말로 반가워요!"초기값을 처리하는 것을 볼 수 있습니다.
이후의 동작은 PublishSubject와 동일합니다.
let behaviorSubject = BehaviorSubject(value: "첫 인사말로 반가워요!")
behaviorSubject.onNext("구독 전의 인사말 !")
behaviorSubject
.subscribe { eventString in
print("onNext - \(eventString)")
} onError: { error in
print("onError - \(error)")
} onCompleted: {
print("onComplete")
} onDisposed: {
print("onDisposed")
}
.disposed(by: disposeBag)
// onNext - 구독 전의 인사말 !
behaviorSubject.onNext("안녕하세요") // onNext - 안녕하세요
구독 시점 이전에 방출된 값이 있다면 해당 event를 처리하는 것을 확인할 수 있습니다.
ReplaySubject
- 초기값이 없습니다.
- 선언된 bufferSize만큼 이벤트를 갖고있다가 구독 시점에 이벤트를 전달합니다.
- Error가 발생하더라도 바로 stream이 끊어지지 않고 갖고있는 이벤트를 방출한 이후 stream이 해제됩니다.
let replaySubject = ReplaySubject<String>.create(bufferSize: 2)
replaySubject.onNext("안녕하세요")
replaySubject.onNext("반갑습니다.")
replaySubject.onNext("개발콩입니다!")
replaySubject.onError(SampleError.error)
replaySubject
.subscribe { eventString in
print("onNext - \(eventString)")
} onError: { error in
print("onError - \(error)")
} onCompleted: {
print("onComplete")
} onDisposed: {
print("onDisposed")
}
.disposed(by: disposeBag)
// onNext - 반갑습니다.
// onNext - 개발콩입니다!
// onError - error
// onDisposed
AsyncSubject
- 초기값이 없습니다.
- 구독시점 이후 onNext로 이벤트가 방출되어도 처리하지 않습니다.
- completed 이벤트가 전달된 이후 가장 최근에 전달된 값을 방출합니다.
let asyncSubject = AsyncSubject<String>()
asyncSubject.onNext("안녕하세요")
asyncSubject.onNext("반갑습니다.")
asyncSubject.onNext("개발콩입니다!")
asyncSubject.onCompleted()
asyncSubject
.subscribe { eventString in
print("onNext - \(eventString)")
} onError: { error in
print("onError - \(error)")
} onCompleted: {
print("onComplete")
} onDisposed: {
print("onDisposed")
}
.disposed(by: disposeBag)
// onNext - 개발콩입니다!
// onComplete
// onDisposed
4개의 Subject의 차이점에 대해서 알아보았습니다.
이 글을 읽고 4개의 Subject에 대해서 차이점을 명확히 알고 적절한 상황에 사용할 수 있으면 좋겠습니다.
'RxSwift' 카테고리의 다른 글
[RxSwift] 구독 방식에 대한 선택 subscribe, bind, drive (0) | 2025.02.28 |
---|---|
[RxSwift] PublishRelay, BehaviorRelay, ReplayRelay (0) | 2025.02.27 |
[RxSwift] ObservableType과 ObserverType (0) | 2025.02.25 |
[RxSwift] RxSwift의 시작 Observable & Observer (0) | 2025.02.24 |
[RxSwift] throttle vs debounce (0) | 2025.02.20 |