RxSwift

[RxSwift] Subject 정리

devharrry 2020. 5. 24. 00:13

안녕하세요. 

 

오늘은 옵저버블이자 옵저버 역할을 하는 Subject에 대해 정리해보려고 합니다. 

 

Subject란 

RxSwift에서 옵저버블에게 새로운 값을 전달하고 subscriber가 새로운 값을 전달 받는 형식입니다. 

 

Subject는 옵저버블이자 옵저버 두 역할을 모두 수행합니다. 

 

next이벤트를 통해서 값을 전달 받고, 이벤트를 수신할 때 마다 subscriber를 통해 방출합니다. 

 

Subject 종류 

Subejct종류로는 PublishSubject, BehaviorSubject, ReplaySubject, Variable가 있습니다. 

 

1) PublishSubject

서브젝트로 전달되는 이벤트를 옵저버에게 전달하는 가장 기본적인 형태의 서브젝트입니다. 

 

즉, 빈 상태로 시작하며 새로운 값을 전달 받을 때에 subscriber를 통해 방출. 

 

 

위 그림에서 첫 번재 가로 라인은 subject, 그 아래 가로 라인은 subscriber를 의미하고, 위 화살표는 subscriber 시점, 아래 화살표는 아이템 방출을 의미합니다. 

그림을 보면 구독한 시점 이후의 아이템만 전달 받는 것을 의미합니다. 

- 주로 언제 사용하는가?

구독된 순간 새로운 이벤트 수신을 알리고 싶을 때.

 

- 특징

해당 서브젝트가 종료되었을 때 구독자에게 종료 이벤트를 전달할 뿐만 아니라 그 이후 구독한 구독자에게도 종료 이벤트를 전달해줍니다. 

 

 

2) BehaviorSubject 

PublishSubject와 다르게 서브젝트를 생성하는 방식이 다릅니다. 하나의 초기 값을 가지고 있어야합니다. 

초기 값을 가지고 있는 상태이기 때문에 초기 값으로 next이벤트로 값이 전달되면서 시작됩니다. 

 

(추가로, 만약 옵저버를 하나 추가했을 경우에 가장 최신의 next값을 새롭게 추가된 옵저버에게 전달합니다.)

 

위 그림을 보면 PublishSubject와 다르게 새롭게 구독을 시작했을 때 직전의 값을 전달 받고 시작합니다. 

 

 - 주로 언제 사용하는가?

뷰를 가장 최신의 데이터로 미리 세팅할 때 

 

3) ReplaySubject 

하나 이상의 새로운 이벤트를 버퍼에 저장하고 옵저버가 구독을 시작하면 버퍼에 있는 모든 이벤트를 전달합니다. 

 

버퍼의 크기를 설정할 수 있으며, 만약 버퍼의 크기가 0이라면 PublishSubject와 동일한 역할을 합니다. 

 

버퍼 사이즈를 2로 가정해봅시다. 그렇기 때문에 subject와 구독자는 동일한 값을 가지고 있고, 

두번째 구독자(마지막 가로 라인)은 1,2가 방출된 후 구독하였지만 버퍼 사이즈 2만큼의 값을 전달 받을 수 있습니다. 

 

ReplaySubject는 코드로 보는게 이해가 빠르기 때문에 한번 작성해보겠습니다. 

 

let disposeBag = DisposeBag()
        
let replaySubject = ReplaySubject<String>.create(bufferSize: 2)
replaySubject.onNext("1")
replaySubject.onNext("2")
replaySubject.onNext("3")
        
replaySubject
    .subscribe {
        print("첫번째 구독자 \($0)")
    }
    .disposed(by: disposeBag)
        
replaySubject
    .subscribe {
        print("두번째 구독자 \($0)")
    }
    .disposed(by: disposeBag)
    
// print
첫번째 구독자 next(2)
첫번째 구독자 next(3)
두번째 구독자 next(2)
두번째 구독자 next(3)

버퍼 사이즈가 2이기 때문에 1은 방출되지 않습니다. 

 

- 주로 언제 사용하는가?

최근 값 1개 외에 더 많은 값이 필요로 할 때. 

 

- 특징

버퍼들은 메모리가 가지고 있으며, 데이터 타입이 메모리를 크게 차지하는 값이라면 메모리 부하가 날 수 있습니다. 

 

4) Variable

BehaviorSubject를 래핑하고 있으며, 현재 값을 상태로 가지고 있습니다. 

 

complete, error이벤트가 발생하지 않으며 variable이 해제될 때 자동으로 complete됩니다. 

 

- 특징 

1)subject, observable과 다르게 새로운 요소를 추가하기 위해서 onNext를 사용할 수 없습니다. 

2)variable은 상태값이기 때문에 에러가 발생하지 않는 것을 보장하기 때문에 error이벤트를 발생시킬 수 없습니다.

3)variable이 해제될 때 자동으로 complete되기 때문에 complete이벤트를 발생시킬 수 없습니다.

 

- 주로 언제 사용하는가?

현재 값을 확인하고 싶을 때.

 

 

참고 - RxSwift: Reactive Programming with Swift - raywenderlich

(https://store.raywenderlich.com/products/rxswift?_ga=2.88706715.1421367013.1516248812-515082446.1516248812)

'RxSwift' 카테고리의 다른 글

[RxSwift] Creating Observables 정리  (0) 2020.05.16
[RxSwift] 옵저버블(Observable)이란?  (1) 2020.05.16
RxSwift란  (0) 2020.05.16
RxSwift Summary 카테고리 포스트 계획  (0) 2020.05.16