Subject와 Relay
Subject
발행할 것이 미리 정해진 Observable과는 다르게 일단 구독을 하고 추후에 발행을 하는 객체가 Subject입니다.
Observable과의 차이
Observable | Subject |
---|---|
누군가가 구독을 해야 발행 | 구독을 하지 않아도 개발자가 원하는 때에 발행 가능 |
각 구독자에게 따로 발행 | 모든 구독자에게 동시에 발행 |
Subject의 종류
Publish Subject
가장 기본이 되는 Subject입니다. 구독하기 전에도 발행할 수도 있지만 구독하지 않으면 이벤트를 받을 수 없습니다.
import RxSwift
//✅ 구현하기 (발행물의 타입을 제네릭으로 선언합니다.)
let subject = PublishSubject<String>()
//✅ 발행하기
//🚫 해당 객체를 구독하기 전에 발행해서 출력되지 않습니다.
subject.onNext("구독전 발행 1")
//✅ 구독하기
//🚫 구독 전에 발행한 것에 대해서는 받을 수 없습니다.
subject.subscribe { event in
print(event)
}
//✅ 구독 이후에도 발행 가능!
subject.onNext("구독 후 발행 1")
subject.onNext("구독 후 발행 2")
//✅ dispose하거나 complete한 다음에는 추가 발행할 수 없다!
subject.dispose()
subject.onCompleted()
subject.onNext("dispose 후 발행 1") //🚫 발행 안됨
//🖨 출력 결과
next(구독 후 발행 1)
next(구독 후 발행 2)
Behavior Subject
초기 값을 가지는 subject입니다. 항상 마지막으로 발행된 값으로 초기 값을 갱신합니다.
import RxSwift
//✅ 초기 값을 가지고 발행합니다.
let subject = BehaviorSubject(value: "원래 초기 값")
//✅ 구독 전에 발행하면 이전 값을 지우고 발행된 값을 초기 값으로 가지고 있습니다.
subject.onNext("새로운 초기 값")
//✅ 구독하는 순간 초기값을 발행합니다.
subject.subscribe { event in
print(event)
}
//✅ 구독자에게 발행하고 현재의 초기 값으로 가지고 있습니다.
subject.onNext("또 새로운 초기 값")
//🖨 출력 결과
next(새로운 초기 값)
next(또 새로운 초기 값)
Relay Subject
Behavior Subject와 유사하게 초기 값을 가지고 있지만 여러 개의 초기 값을 가지고 있다는 차이점이 있습니다.
import RxSwift
//✅ buffer size를 정의하여 발행합니다.
let subject = ReplaySubject<String>.create(bufferSize: 2)
//✅ 마지막 n개의 발행물을 buffer size만큼 가지고 있다가 발행합니다.
subject.onNext("발행 1")
subject.onNext("발행 2")
subject.onNext("발행 3")
//✅ 구독 하기
subject.subscribe {
print("처음 구독: \($0)")
}
//👉 발행된 값 중에 2개가 저장되어 있다가 발행됩니다.
//✅ 추가적으로 발행하는 것은 정상적으로 발행되고 buffer size만큼 최신의 발행물을 갱신하면서 저장해서 가지고 있습니다.
subject.onNext("발행 4")
subject.onNext("발행 5")
subject.onNext("발행 6")
//✅ 새롭게 구독하면 저장해둔 마지막 2개의 발행인 5, 6을 발행합니다.
subject.subscribe {
print("두번째 구독: \($0)")
}
//🖨 출력 결과
처음 구독: next(발행 2) //👉 초기값 2개 발행
처음 구독: next(발행 3)
처음 구독: next(발행 4)
처음 구독: next(발행 5)
처음 구독: next(발행 6)
두번째 구독: next(발행 5) //👉 갱신된 초기값 2개 발행
두번째 구독: next(발행 6)
Relay
크게는 Subject와 유사한 개념이라고 보시면 됩니다. 하지만 결정적인 차이가 몇 가지 있습니다.
- Relay는 Subject와 다르게 RxSwift가 아니라 RxCocoa에 정의되어 있습니다.
- Subject는 completed 혹은 error의 이벤트가 발생하면 구독을 종료합니다. 반면에 Relay는 completed나 error 이벤트를 발생시키지 않습니다. dispose될 때까지 계속 발행할 수 있습니다. 이러한 특성 때문에 Relay는 UI에 더 사용하기 적합합니다.
종류
Publish Relay
Publish Subject와 거의 동일한 객체입니다. 구독하기 전에 발행된 값은 무시되고 구독하고 발행된 값만 출력되는 모습을 볼 수 있습니다.
import RxCocoa
//✅ 구현하기
let relay = PublishRelay<String>()
//✅ 발행하기
//👉 Subject와는 다르게 accept라는 키워드로 발행
relay.accept("발행 1")
//✅ 구독하기
relay.subscribe {
print($0)
}
relay.accept("발행 2")
relay.accept("발행 3")
//🖨 출력 결과
next(발행 2)
next(발행 3)
Behavior Relay
RxSwift에 있던 Variable이라는 클래스를 대체해서 사용할 수 있는 클래스입니다. (Variable은 deprecated 되었습니다.) 초기 값을 가지고 있고 구독하면 초기값을 발행합니다. 그리고 해당 초기 값이 변경될 때 마다 발행됩니다.
import RxCocoa
//✅ 초기값을 가지고 선언!
let relay = BehaviorRelay(value: "원래 초기 값")
//🚫 value를 직접 수정할 수 없습니다! 👉 readOnly
//relay.value = "새로운 초기 값"
//✅ value를 새로 세팅하기
relay.accept("새로운 초기 값")
//✅ asObservable로 구독할 수 있음
relay.asObservable()
.subscribe {
print($0) //👉 구독하자마자 초기값이 발행됨!
}
//✅ 구독하고 있을때 초기 값을 바꾸면 발행된다.
relay.accept("다시 또 새로운 초기 값")
//🖨 출력 결과
next(새로운 초기 값) //👉 구독하자마자 초기 값 발행
next(다시 또 새로운 초기 값) //👉 초기 값 바꾸면 새로 발행
Author And Source
이 문제에 관하여(Subject와 Relay), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@comdongsam/Subject와-Relay저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)