본문 바로가기

Swift/RxSwift

[🔥Rx뿌셔] Subject - Replay Subject

728x90

Replay Subject

Buffer Size만큼의 최신 값을 저장했다가 emit하는 Subject 

Relplay Subject는 이전에 방출됐던 요소들을 버퍼에 저장해 두었다가 새로운 구독자가 구독되었을 때 같이 넘겨주는 방식의 Subject

 

 

이미지로 나타내면 아래와 같다.

이전에 설명했던, Behavior Subject와 비슷하다.

✔️ 다른 점이 있다면 Behavior Subject와 다르게 제일 처음 구독자를 위한 초기값을 설정할 필요가 없고,

✔️ 가장 최근에 방출된 요소들의 (=전달받을 요소들의) 최대 개수를 지정할 수 있다. 

 

 

코드로 구현하면 아래와 같다.

let replay = ReplaySubject<Int>.create(bufferSize: 3)

Replay Subject는 다른 Subject와 다르게 .create()으로 선언한다.

그리고 가장 최근에 방출된 요소들의 최대 개수는 bufferSize라는 파라미터로 받는다.

 

예를 들어서 bufferSize를 3이라고 하면 구독하기 전에 방출되었던 요소를 3개까지 갖고 와서 그 요소를 시작으로 다음 방출되는 요소들을 받는 것이다.

 

 

아래와 같은 상황이 있다고 해보자.

// subscriber 1
replaySubject.subscribe(onNext: { element in
    print("subscriber1 \(element)")
}).disposed(by: disposeBag)

replaySubject.onNext(1)
replaySubject.onNext(2)

// subscriber 2
replaySubject.subscribe(onNext: { element in
    print("subscriber2 \(element)")
}).disposed(by: disposeBag)

replaySubject.onNext(3)
replaySubject.onNext(4)

// subscriber 3
replaySubject.subscribe(onNext: { element in
    print("subscriber3 \(element)")
}).disposed(by: disposeBag)

replaySubject.onNext(5)

 

subscriber1의 입장에서는 구독을 시작하고 이벤트가 방출되었으므로 1, 2, 3, 4, 5에 대한 이벤트를 모두 전달받을 수 있다.

subscriber2의 입장에서는 구독을 하기 전 2개의 이벤트에 대해 전달받을 수 있고, 그 이후로의 이벤트를 전달받을 수 있으므로 1, 2, 3, 4, 5의 이벤트를 받을 수 있다.

subscriber3의 입장도 마찬가지로 구독을 하기 전 2개의 이벤트+이후의 이벤트에 대해 전달받기 때문에 3, 4, 5에 대해 전달받는다.

 

따라서 위의 코드를 실행하면,

// subscriber1 1
// subscriber1 2
// subscriber1 3
// subscriber1 4
// subscriber1 5

// subscriber2 1
// subscriber2 2
// subscriber2 3
// subscriber2 4
// subscriber2 5

// subscriber3 3
// subscriber3 4
// subscriber3 5

위와 같은 결과를 얻을 수 있다.

 

 

Replay Subject에서 주의할 점은,

위와 같이 bufferSize를 통해서 buffer의 크기를 마련하는 것은, 즉 buffer에 구독 이전에 방출된 요소들을 저장하는 행위는 엄연히 메모리를 사용하는 행위이기 때문에 이미지, 영상 데이터들을 ReplaySubject로 관리하는 경우, 남발하지 않는 것이 좋다.

 


정리를 하자면 아래와 같다.

  • 버퍼를 두고 초기화를 진행하며, 버퍼 사이즈 만큼의 값들을 유지하면서 등록된 subscriber에게 버퍼 내용 혹은 최신 값을 방출하는 subject이다.
  • 위의 이미지에서 볼 수 있는 것처럼 새로운 subscriber가 생기면 버퍼에 등록된 이벤트를 그 subscriber에게 전달한다.
  • 주의할 점은 버퍼들이 모두 메모리에서 관리된다는 점이다.
    • 따라서 이미지, Array와 같이 큰 사이즈의 데이터를 버퍼에 넣는 것은 지양해야 한다.
  • 검색창과 같이 최근 내역을 필요로 하는 데이터를 구현할 때 적절하다. 
    • 최근에 저장된 값을 지속적으로 관리할 수 있다. 

 

🔥 정리
Subject를 구독할 때 가장 최근에 방출되었던 1개 이상의 요소들을 전달받고 싶을 때는 Replay Subject를 이용한다.