RxSwift) RxRelay란?

Havi·2021년 4월 7일
0

RxSwift 기초

목록 보기
13/14

RxRelay란?

RxRelay의 경우 RxCocoa 내부에서 import 되어있기 때문에 RxCocoa를 import하고 있을 경우 따로 import하지 않아도 된다.

Relay는 Subject의 Wrapper 클래스로 종료 이벤트로 종료되지 않는다는 특징이 있다.

Relay는 on()메소드 대신 accept()메소드로 element를 전달받아 subscriber에게 방출한다.

BehaviorRelay, PublishRelay 두가지 종류의 Relay를 제공하며 최근값을 가지는지, 안가지는지로 구분한다.

아래와 같이 bind함수에서 complete가 불릴경우 break로 무시해준다.

public func bind(to relays: PublishRelay<Element>...) -> Disposable {
        return bind(to: relays)
    }

private func bind(to relays: [PublishRelay<Element>]) -> Disposable {
        return subscribe { e in
            switch e {
            case let .next(element):
                relays.forEach {
                    $0.accept(element) // Relay 내부의 Subject에 next이벤트를 흘려보낸다.
                }
            case let .error(error):
                //디버그 모드면 런타임 에러를, 릴리즈 모드면 그냥 에러 메시지를 print만 한다.
                //즉, 어떻게 해서든 내부 subject에 에러가 흘러가지를 않는다.
                rxFatalErrorInDebug("Binding error to publish relay: \(error)")
            case .completed:
                break
            }
        }
    }

PublishSubject 구현

/// PublishRelay is a wrapper for `PublishSubject`.
///
/// Unlike `PublishSubject` it can't terminate with error or completed.
public final class PublishRelay<Element>: ObservableType {
    private let _subject: PublishSubject<Element>
    
    // Accepts `event` and emits it to subscribers
    public func accept(_ event: Element) {
        self._subject.onNext(event)
    }
    
    /// Initializes with internal empty subject.
    public init() {
        self._subject = PublishSubject()
    }

    /// Subscribes observer
    public func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
        return self._subject.subscribe(observer)
    }
    
    /// - returns: Canonical interface for push style sequence
    public func asObservable() -> Observable<Element> {
        return self._subject.asObservable()
    }
}

BehaviorRelay 구현

/// BehaviorRelay is a wrapper for `BehaviorSubject`.
///
/// Unlike `BehaviorSubject` it can't terminate with error or completed.
public final class BehaviorRelay<Element>: ObservableType {
    private let _subject: BehaviorSubject<Element>

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

    /// Current value of behavior subject
    public var value: Element {
        // this try! is ok because subject can't error out or be disposed
        return try! self._subject.value()
    }

    /// Initializes behavior relay with initial value.
    public init(value: Element) {
        self._subject = BehaviorSubject(value: value)
    }

    /// Subscribes observer
    public func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
        return self._subject.subscribe(observer)
    }

    /// - returns: Canonical interface for push style sequence
    public func asObservable() -> Observable<Element> {
        return self._subject.asObservable()
    }
}
profile
iOS Developer

0개의 댓글