Subject
Observable
이자 Observer
이다.
.next(value)
를 받고, 수신할 때마다 Subscriber
에게 방출한다.
- Sequence가 종료된 Subject를 subscription할 경우, 마지막 Event(
.error
혹은 .completed
) 를 방출한다.
- Sequence가 종료된 Subject에 대하여
dispose
를 호출하면 오류가 출력된다.
Relay와의 차이점
- Relay는
complete
나 error
를 받지 않는다.
- Relay는 observable이 종료되어도, relay 내의 subject 종료되지 않는다.
- 따라서, observable의 종료가 절대적으로 보장되지 않는다면, relay.bind 하는 것은 바람직하지 않다.
PublishSubject
- 초기값이 존재하지 않으며, 새로운 값만을
Subscriber
에게 방출한다.
let disposeBag = DisposeBag()
let subject = PublishSubject<String>()
subject.on(.next("Before subscribed"))
subject.subscribe {
print("🟢", $0)
}
subject.on(.next("1"))
subject.on(.next("2"))
subject.subscribe {
print("🔴", $0)
}
subject.on(.next("3"))
subject.on(.error(CustomError.error))
subject.on(.next("After error"))
subject.subscribe {
print("🟡", $0)
}.disposed(by: disposeBag)
subject.on(.next("4"))
BehaviorSubject
- 하나의 초기값을 갖으며, 새로운
Subscriber
에게 초기값 또는 최신 값을 방출한다.
let disposeBag = DisposeBag()
let subject = BehaviorSubject<String>(value: "Initial value")
subject.on(.next("Before subscribed"))
subject.subscribe {
print("🟢", $0)
}
subject.on(.next("1"))
subject.on(.next("2"))
subject.subscribe {
print("🔴", $0)
}
subject.on(.next("3"))
subject.on(.error(CustomError.error))
subject.on(.next("After error"))
subject.subscribe {
print("🟡", $0)
}.disposed(by: disposeBag)
subject.on(.next("4"))
ReplaySubject
- 버퍼 사이즈 만큼의 값들을 유지하며, 새로운
Subscriber
에게 버퍼 사이즈만큼 값을 방출한다.
- 버퍼는 메모리에 할당되어져 있기 때문에, 이미지와 같이 큰 용량의 것을 버퍼로 갖지 않도록 한다.
.error
가 발생하여도 우선 버퍼에 있는 값들은 전달된다.
let disposeBag = DisposeBag()
let subject = ReplaySubject<String>.create(bufferSize: 2)
subject.on(.next("Before subscribed"))
subject.subscribe {
print("🟢", $0)
}
subject.on(.next("1"))
subject.on(.next("2"))
subject.on(.next("3"))
subject.subscribe {
print("🔴", $0)
}
subject.on(.next("4"))
subject.on(.error(CustomError.error))
subject.on(.next("After error"))
subject.subscribe {
print("🟡", $0)
}.disposed(by: disposeBag)
subject.on(.next("5"))
AsyncSubject
.comleted
되어야만 값이 나온다.
.completed
이전의 event에 대해서는 어떠한 것도 방출하지 않는다.
- subscribe하여도 마찬가지로
.comleted
되기 전 까지는 아무런 값을 방출하지 않는다.
- 종료 이벤트를 받으면
.next(lastElement) + .completed
를 방출한다.
- 종료된 이후에 subscribe할 경우,
.next(lastElement) + .completed
를 받게 된다.
- 만약 값이 없이 그냥
.completed
된 경우는 값 없이 그냥 completed만 받게 되며, error의 경우에는 .error
를 받게 된다.
let subject = AsyncSubject<Int>()
subject.onNext(0)
subject.onNext(1)
subject.debug("🟢")
.subscribe()
.disposed(by: disposeBag)
subject.onNext(2)
subject.onCompleted()
subject.onNext(3)
subject.debug("🔴")
.subscribe()
.disposed(by: disposeBag)
comleted라고 오타가 난거 같아요;;
덧: 잘 보고 있습니다. 감사합니다.