Reference Post
naljin
김종권의 iOS 앱 개발 알아가기
ex) PublishSuject는 일종의 출판사와 같은 작업
-> 출판사에서 "Is Anyone Listening?"이란 내용을 받음 (.onNext)
-> 구독 (.subscribe)
-> 현재 벌어진 일만 emit. (.subscribe 했을 경우 "Is Anyone Listening?"은 과거에 발생했던 일이라 emit하지 않음.)
-> 뒤에 1과 2 이벤트 추가 시 (현재 벌어진 일), 이것들은 emit
example(of: "PublishSubject") {
let subject = PublishSubject<String>()
subject.onNext("Is Anyone Listening?")
let subscriptionOne = subject
.subscribe(onNext: { string in
print(string)
})
subejct.onNext("1") // print: 1
subject.onNext("2") // print: 2
}

예제 코드
example(of: "PublishSubject") {
let subject = PublishSubject<String>()
subject.onNext("Is Anyone Listening?")
// 첫 번째 구독 요청
let subscription1 = subject
.subscribe(onNext: { string in
print(string)
})
subject.onNext("1")
subject.onNext("2")
// prints : 1, 2
// 두 번째 구독 요청
let subscription2 = subject
.subscribe({ event in
print("2)", event.element ?? event)
})
subject.onNext("3") // print: 2) 3
subscription1.dispose()
subject.onNext("4") // print: 2) 4
subject.onCompleted() // print: 2) completed
subject.onNext("5") // none of print
subscription2.dispose()
let disposeBag = DisposeBag()
subject.
subscribe {
print("3)", $.element, ?? $0) // print: 3) completed
}
.disposed(by: disposeBag)
}
☑️ PublishSubject는 현재 구독 요청한 대상만 관심을 갖음 -> subejct.onNext("3")에서 subscriptoin1 관련된 호출은 하지 않음!
☑️ 이벤트를 추가할 땐, subject. 으로 접근하여 추가! (onNext, on)
☑️ subejct.onCompleted() 할 시, 구독 종료..~
🚨subscrbier에게 이벤트를 방출(emit)시키는 방법
🤔 PublishSubject 사용은 언제 하면 좋을까?

예제코드
enum MyError: Error {
case anError
}
examplease(of: "BehaivorSubject") {
// BehaviorSubject는 초기값이 필수🌟이므로 초기값 삽입
let subject = BehaviorSubject(value: "초기값")
let disposeBag = DisposeBag()
subject.onNext("X")
subejct
.subscrbie { print("1)", $0)
}
.disposeBag(by: disposeBag)
// print: 1) next(X)
subject.onError(MyError.anError)
// print: 1) error(anError)
subject
.subscribe { print("2)". $0)
}
.disposed(by: disposeBag)
// print: 2) error(anError)
}
☑️BehaviorSubject는 초기화 값이 필수이며, 항상 저장되어 있는 최신값을 방출(emit)
🤔 BehaviorSubject는 언제 사용하면 좋을까?

🚨버퍼 사이즈는 메모리에 할당되므로 버퍼 사이즈가 커질수록 메모리에 큰 부하를 갖는 것을 주의하자🚨
예제 코드
example(of: "ReplaySubject") {
let subject = ReplaySubject<String>.create(bufferSize: 2)
let disposeBag = DisposeBag()
subject.onNext("1")
subject.onNext("2")
subject.onNext("3")
subject
.subscribe {
print("1)", $0)
}
.disposed(by: disposeBag)
/*
prints
1) next(2)
1) next(3)
*/
subject
.subscribe {
print("2)", $0)
}
.disposed(by: disposeBag)
/*
prints
2) next(2)
2) next(3)
*/
subject.onNext("4")
/*
prints
1) next(4)
2) next(4)
*/
subject.onError(MyError.anError)
/*
prints
2) error(anError)
2) error(anError)
*/
// subejct.dispose()
subject.subscribe {
print("3)", $0)
}
.disposed(by: disposeBag)
/*
prints
3) next(3)
3) next(4)
3) error(anError)
*/
☑️ 버퍼 사이즈가 2이므로 구독하면 항상 2개씩 emit
☑️ subject.onError() 해도 print(3, $0) 부분에서 next(3), next(4) 출력됨.. -> subject.onError() 후에 subject.dispose()를 넣으면 해결됨
🤔 ReplaySubject는 언제 사용하면 좋을까?
PublishRelay 예제 코드
example(of: "PublishRelay:) {
let relay = PublishRelay<String>()
let disposeBag = DisposeBag()
relay.accept("똑 똑, 계시나요?")
relay
.subscribe(onNext: { print($)
})
.disposed(by: disposeBag)
relay.accept("1") // print: 1
☑️ relay의 추가는 .accept() 로 접근
☑️ onError, onCompleted 사용 불가
BehaviorRelay 예제 코드
example(of: "BehaviorRelay") {
let relay = BehaviorRelay(value: "초기값")
let disposeBag = DisposeBag()
realy.accept("새로운 값")
relay
.subscribe { print("1)", $0)
}
.disposed(by: disposeBag)
// print: 1) next("새로운 값")
relay.accept("1")
// print: 1) next(1)
relay
.subscribe { print("2)", $0)
}
.disposed(by: disposeBag)
// print: 2) next(1)
relay.accept("2")
// print: 2) next(2)
☑️ .accept()로 다가가며, onError, onCompleted 사용 불가.