안녕하세요🐶
빈지식 채우기의 비니🙋🏻♂️ 입니다.
이번 포스팅에서는 Subject에서 파생된 Relay라는 개념에 대해 알아보도록 하겠습니다.
Subject에 생소하신 분들은 아래 포스팅을 참고해주시면 감사드리겠습니다.
1. 개요
Relay의 경우 RxSwift에서 제공되는 것이 아니라 RxCocoa에서 제공하고 있습니다.
왜냐하면 Relay를 사용하여 UI 이벤트를 쉽게 구현하고 처리할 수 있기 때문입니다.
또한 Subject 와는 다르게 onError, onCompleted를 사용할 수 없고 오직 onDispose의 경우에서만 작동이 멈추게 됩니다.
Subject 와는 다르게 onNext 대신 Accept 를 통해 데이터를 방출합니다.
우선, 간단하게 예를 들어 아래와 같은 Subject가 있다고 가정을 해보겠습니다.
let text = PublishSubject<String>()
let textOb = text.asObservable()
textOb.subscribe { text in
print(text)
}.disposed(by: disposeBag)
text.onNext("안녕")
text.onNext("안녕하세")
text.onNext("안녕하세요")
PublishSubject ( 구독 이후에 전달되는 값을 방출 ) 로 인해 onNext로 전달된 값들에 대해 방출하고 있습니다.
다만 여기서 Error 가 발생하면 어떻게 될까요?
let text2 = PublishSubject<String>()
let textOb2 = text2.asObservable()
textOb2.subscribe { text in
print(text)
}.disposed(by: disposeBag)
text2.onNext("안녕")
text2.onNext("안녕하세")
text2.onError(MyError.error) // 에러 발생
text2.onNext("안녕하세요")
Error가 발생 시점 이후에 전달되는 값들에 대해서는 방출하지 못하게 됩니다.
만약 실제 앱에서 UI 이벤트에 대해 이런 일이 생기면 큰일이 발생할 수 있기 때문에 여기서 사용되는 개념이
Relay
입니다. 왜냐? Subject 와는 다르게 onError 와 onCompleted를 사용할 수 없기 때문입니다.
이렇게 정의된 코드를 살펴보면, 내부적으로 Subject를 프로퍼티로 가지고 있는 것을 확인할 수 있습니다.
그리고 앞서 말했듯이 데이터 방출을 Accept를 사용하고 있는데,
사실 내부에서 프로퍼티 subject를 통해 onNext 를 호출에서 이벤트를 전달하는 것을 확인할 수 있습니다.
2. Relay의 종류
2-1. PublishRelay
PublishSubject의 파생된 것으로 구독 이후에 시점에서 전달된 값을 방출하고 있습니다.
위와 동일한 예시를 PublishRelay를 통해 구현해보도록 하겠습니다.
let relay = PublishRelay<String>()
let relayOb = relay.asObservable()
relayOb.subscribe { text in
print(text)
}.disposed(by: disposeBag)
relay.accept("안녕")
relay.accept("안녕하세")
relay.accept("안녕하세요")
Subject와는 다르게 onError에 대한 구현이 없어서 UI 구성에서 주로 사용하고 있습니다.
2-2. BehaviorRelay
BehaviorSubject에서 파생된 것으로 초기 값을 가지고 있으며,
가장 최근에 전달된 값을 방출하는 특징을 가지고 있습니다.
let relay2 = BehaviorRelay<[Int]>(value: [1, 2, 3])
let relayOb2 = relay2.asObservable()
var value = relay2.value
relayOb2.subscribe { data in
print(data)
}.disposed(by: disposeBag)
// 값 추가 방법 1
relay2.accept(value + [4])
// 값 추가 방법 2
value.append(5)
relay2.accept(value)
PublishRelay 와 별개로,
BehaviorRelay는 value 라는 프로퍼티를 통해 최근에 방출된 값을 가지고 올 수 있습니다.
또한 초기 정의된 [1, 2, 3] 배열에 값을 추가하려면 어떻게 해야 할까요?
위에 예로 제시된 코드와 같이 두가지 방법이 존재합니다.
1. accept 시 value에 값을 추가한다.
2. 일반 배열처럼 append를 통해 값을 추가한다.
3. 정리
Subject | Relay | |
특징 | 1. onNext, onComplete, onError 가 존재 | 1. accept 만 존재 2. UI 이벤트 구성에 특화 3. Dispose 에 의해서만 종료 |
데이터 방출 | onNext | accept |
이상으로 Relay 포스팅을 마치겠습니다.
전체 소스는 아래와 같이 첨부하도록 하겠습니다.
import Foundation
import RxSwift
import RxCocoa
enum MyError: Error {
case error
}
class Relay {
func relay() {
let disposeBag = DisposeBag()
print("----------------------------------------------------------")
let text = PublishSubject<String>()
let textOb = text.asObservable()
textOb.subscribe { text in
print(text)
}.disposed(by: disposeBag)
text.onNext("안녕")
text.onNext("안녕하세")
text.onNext("안녕하세요")
print("----------------------------------------------------------")
let text2 = PublishSubject<String>()
let textOb2 = text2.asObservable()
textOb2.subscribe { text in
print(text)
}.disposed(by: disposeBag)
text2.onNext("안녕")
text2.onNext("안녕하세")
text2.onError(MyError.error)
text2.onNext("안녕하세요")
print("----------------------------------------------------------")
let relay = PublishRelay<String>()
let relayOb = relay.asObservable()
relayOb.subscribe { text in
print(text)
}.disposed(by: disposeBag)
relay.accept("안녕")
relay.accept("안녕하세")
relay.accept("안녕하세요")
print("----------------------------------------------------------")
let relay2 = BehaviorRelay<[Int]>(value: [1, 2, 3])
let relayOb2 = relay2.asObservable()
var value = relay2.value
relayOb2.subscribe { data in
print(data)
}.disposed(by: disposeBag)
// 값 추가 방법 1
relay2.accept(value + [4])
// 값 추가 방법 2
value.append(5)
relay2.accept(value)
print("----------------------------------------------------------")
}
}
다음 포스팅은 Driver에 대해 알아보겠습니다.
감사합니다~~
참고
'iOS 🖥️ > RxSwift' 카테고리의 다른 글
[RxSwift] Traits ( Single, Maybe, Completable ) (0) | 2024.01.18 |
---|---|
[RxSwift] Debounce, Throttle (0) | 2024.01.17 |
[RxCocoa] Driver (0) | 2024.01.17 |
[ RXSwift ] Subject (2) | 2024.01.15 |
[ RxSwift ] Operator (0) | 2024.01.11 |