study record

[RxSwift] Subject와 Relay 본문

iOS/RxSwift

[RxSwift] Subject와 Relay

asong 2022. 3. 14. 11:18

Subject

실시간으로 Observable에 값을 추가하고, Subscriber에게 이벤트나 값을 방출할 수 있는 것.

Observable이자 Observer인 것이 Subject이다. Subject를 통해 실시간으로 값을 추가하고 구독할 수 있다.

Subject를 사용하여 Cold Observable을 Hot Observable로 변환할 수 있다.

 

Relay란?

Relay Class는 RxCocoa4에서 구현되었고, PublishRelay와 BehaviorRelay 클래스가 존재한다.

RxSwift인 Subject와 다르게 Relay는 RxCocoa의 클래스이다.

또한 Relay는 Subject와 다르게 onNext(_:)가 아닌 acceept(_:)를 통해 새로운 이벤트를 전달한다.

그리고 subsribe하고 싶을 때 asObservable을 사용한다.

 

PublishRelay

PublishRelay는 PublishSubject의 Wrapper클래스이다.

PublishSubject의 특성처럼 구독 이후의 발생하는 이벤트들만 알 수 있다.

 

- 언제?

onError나 onCompleted를 무시하여 죽지 않는 Observable 시퀀스를 만들고 싶을 때!

 

public final class PublishRelay<Element>: ObservableType {
  private let _subject: PublishSubject<Element>
  public init() {
      _subject = PublishSubject()
  }
  
   // Accepts `event` and emits it to subscribers
    public func accept(_ event: Element) {
        self._subject.onNext(event)
    }
}

 

사용 예시

var publishRelay = PublishRelay<Any>()

publishRelay.subscribe(onNext: { element in
    print(element)
}).disposed(by: disposeBag)

publishRelay.accept("hi🙂")

BehaviorRelay

BehaviorRelay는 BehaviorSubject의 Wrapper 클래스이다.

.value를 통해서 현재의 값을 가져올 수 있다.

variable이 Deprecate되면서 대신에 BehaviorRelay를 사용한다.

 

- 언제?

BehaviorSubject를 사용하고 싶은데 onError와 onCompleted 이벤트를 모두 무시하여 시퀀스를 보호하고 싶을 때!

 

public final class BehaviorRelay<Element>: ObservableType {
  private let _subject: BehaviorSubject<Element>

  public var value: Element {
      return try! _subject.value()
  }

  public init(value: Element) {
      _subject = BehaviorSubject(value: value)
  }
  
    /// Accepts `event` and emits it to subscribers
    public func accept(_ event: Element) {
        self._subject.onNext(event)
    }
}

사용예시

var behaviorRelay = BehaviorRelay<String>(value: "Start with me")

behaviorRelay.subscribe(onNext: { element in
    print(element)
}).disposed(by: disposeBag)

behaviorRelay.accept("hi🙂")

Subject와 Relay의 차이점

Subject.completed, .error 의 이벤트가 발생하면 subscribe가 종료된다.

Relay .completed, .error를 발생시키지 않고 Dispose되기 전까지 계속 작동하기 때문에 UI Event에서 사용하기 적절하다.

오직 accept 이벤트만 방출하고 onError나 onCompleted가 방출되도 무시하기 때문에 시퀀스가 절대 죽지 않는다.

 

 

참고:

https://jinshine.github.io/2019/01/05/RxSwift/3.Subject%EB%9E%80/

https://joycestudios.tistory.com/88

https://eunjin3786.tistory.com/37

https://www.notion.so/BehaviorRelay-23c98598c58348d9b0cc422b5669de80