[RxSwift] Subjects, Relays

Martin Kim·2022년 4월 25일
0

RxSwift

목록 보기
2/8

일반적으로 앱을 개발할때 필요한 것은 새로운 값을 런타임에 observable에 수동으로 추가하고 subscriber에게 방출하는 것이다. 우리가 원하는 것은 observable과 observer의 역할을 모두 수행할 수 있어야 하고 이것을 Subject라고 한다.

Subjects

  • 마치 신문 발행인과 같이 정보를 받고, subscribers에게 정보를 발행한다.
  • 선언된 제네릭 타입으로만 element를 수신하고 발행할 수 있다.
  • 이벤트 방출하기 이전에 설정된 subscribers에게만 이벤트가 발행된다.
    • subscribe를 설정하기 이전의 이벤트는 구독할 수 없다
  • subjects 는 observable과 observer의 역할 두 가지를 수행한다.
  • 4가지 종류의 subject가 있다.

PublishSubject

  • 텅 빈 상태로 시작하고, 오직 새로운 element만 subscribers에게 방출한다.
  • Publish Subjects는 completed나 error이벤트가 발생하기 전 까지 subscribers가 구독한 시점으로부터 새로운 이벤트를 구독받길 원할 때 유용하게 사용할 수 있다.
  • 그리고 종료 시점에 종료 이벤트(completed, error)를 구독자들에게 방출한다.

BehaviorSubject

  • 초기값을 가지고 시작하고, 이를 방출하거나 시퀀스의 가장 마지막 element를 새로운 subscribers에게 방출한다.

  • 즉, 새로운 subscriber가 설정되면 즉시 시퀀스의 가장 마지막이었던 element를 방출한다.

  • 반드시 초기값을 제공해야 하며, 그렇지 못할것 같으면 PublishSubject를 사용하거나, 데이터를 옵셔널로 설게하는것을 고려해보자.

  • 만약 도중에 에러가 발생하면, 새로운 subscriber가 설정될 때마다 해당 에러만 방출한다. 더 이상의 next이벤트는 실행되지 않는다.

  • BehaviorSubject는 가장 최근의 값으로 미리보기를 채우려고 할 때 유용하다. 예를 들어, 앱이 새로운 데이터를 로드하여 유저 프로필 데이터를 설정하기 전까지 이전의 데이터로 미리 데이터를 세팅할 때 사용할 수 있다.

  • 최신 값보다 더 많은 이전 정보들을 보여주고 싶다면 ReplaySubject를 고려하자

ReplaySubject

  • 선택한 지정 크기까지 자신이 방출하는 최신 element를 일시적으로 캐쉬처리하거나 버퍼한다. 그러고 나서 새로운 subscribers들에게 해당 버퍼들을 재생한다. 확장된 BehaviorSubject라고 생각하면 쉽다.
  • replaysubject를 사용할 때 중요한 점은, 이 버퍼는 메모리에 유지된다는 것이다. 만약 큰 버퍼 사이즈를 이미지 같이 하나하나가 많은 메모리를 잡아먹는 리소스를 위해 설정한다면, 자살행위나 다름이 없다.
  • 또 다른 사항은 배열을 요소로 replaysubject 만드는 것이다. 방출된 요소는 각각 배열일 것이므로 주의하지 않으면 많은 메모리를 차지하게 될 것이다.
  • 또 중요한 점은, replaysubject가 에러 등 멈춤 이벤트로 종료되었을때, 새로운 subscribers에게 이전의 element들이 여전히 잘 전달된다는 것이다. 왜냐하면 element들을 저장하고 있는 버퍼는 계속해서 메모리에 유지되고 있기 때문이다. (단, 멈춤 이벤트 자체는 버퍼에 들어가지 않기 때문에 이를 제외한 이전 버퍼사이즈 만큼의 요소가 방출된다)
  • dispose이후에 새로운 subscriber를 설정하면 오류가 발생한다.

AsyncSubject

  • 오직 시퀀스의 마지막 next이벤트 만을 방출하고, 오직 completed 이벤트 만을 받을 때 발생한다. 거의 사용되지 않는다.

Relays

RxSwift는 또한 Relays란 컨셉을 제공한다.(PublishRelay, BehaviorRelay)

위의 Subject들로 대부분을 커버할 수 있지만, 단순히 Observable의 현재의 값이 무엇인지를 알고 싶을 때 Relay를 사용한다. 이들은 각각의 Subject를 감싸고 있지만, 오직 next 이벤트만을 받아들이고 전달한다.

다른 observable 타입들과는 달리 accept 메서드를 사용하여 값을 추가한다. 다르게 말하자면, onNext를 사용하지 않는다. 왜냐하면 relays는 오직 값을 accept만 하기 때문이다. error나 completed 이벤트를 추가할 수 없다.

  • PublishRelay는 PublishSubject를, BehaviorRelay는 BehaviorSubject를 래핑한다. 좁은 Subject라고 생각하면 편하다.
  • BehaviorRelay의 .value 프로퍼티로 현재 값을 가져올 수 있다. 즉, 구독을 구현하지 않아도 현재의 값을 즉시 확인할 수 있어 편리하다.

출처: Raywenderlich RxSwift

profile
학생입니다

0개의 댓글