Swift

[RxSwift] RxRelay 그리고 Combine

삼쓰_웅쓰 2024. 6. 25. 13:02
반응형

BehaviorSubject를 래핑하는 클래스다.
BehaviorRelay는 BehaviorSubject와 마찬가지로 상태값을 갖고 있지만,
료(terminate) 되지 않는다. error도 없고 completed도 없다.

/// 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>

 

BehaviorSubject 는 Observable을 상속받아 별다른 처리 없이 바로 사용이 가능하지만
BehaviorRelay는 달리 Observable을 타입으로 바로 사용은 못하지만 asObservable로 변환하여 사용이 가능하다.

BehaviorSubject는 onNext로 값을 업데이트 하지만 BehaviorRelay는 accept를 사용한다.
하지만 내부적으로 보면 이 또한 그저 accept로 받아서 내부적으로 subject에 onNext 해준다.

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

 

이렇듯 주요 특징은 error, completed가 없고 종료되지 않는다는 것이다.
따라서 value를 throw처리 없이 바로 사용이 가능하다.

/// 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()
}

 

Combine

Combine에서 유사한 동작을 찾아보면 CurrentValueSubject가 있다.

import Combine

// 초기값을 가지는 CurrentValueSubject 생성
let subject = CurrentValueSubject<String, Never>("초기값")

// 구독 설정
let cancellable = subject.sink { value in
    print("구독된 값: \(value)")
}

// 새로운 값 설정
subject.send("새로운 값")

// 현재 값에 접근
print("현재 값: \(subject.value)")

// 완료 이벤트 전달
subject.send(completion: .finished)

// 메모리 해제
cancellable.cancel()

Combine 에서 Relay처럼 종료되지 않는 완벽하게 동일한 동작은 없지만,
value를 바로 쓸 수 있고, Error타입을 Never로 하면 value만 sink 할 수 있으니
굳이 Relay같은 게 별도로 필요하지 않은 느낌이다.

var currentValueSubject = CurrentValueSubject<String, Never>("")

...
currentValueSubject.value

currentValueSubject.sink { value in

}
반응형