[회고] 신입 iOS 개발자가 되기까지 feat. 카카오 자세히보기

🍎 Apple/Combine & Rx

[RxSwift] Subject

inu 2022. 2. 16. 00:53
반응형

저번 게시글( [RxSwift] Observable & Operator )에 이어 오늘은 Subject에 대해서 공부해봤어요.


Subject

Subject는 Observable이자 Observer인 존재입니다. 값을 수동으로 추가할 수 있고, 해당 값을 이를 구독중인 Subscriber에게 발행할 수 있습니다.

 

아래 예시를 봅시다.

example(of: "PublishSubject") {

    // 1
    let subject = PublishSubject<String>()

    // 2
    subject.onNext("Is anyone listening?")

    // 3
    let subscriptionOne = subject
        .subscribe(onNext: { (string) in
            print(string)
        })

    // 4
    subject.on(.next("1"))        //Print: 1

    // 5
    subject.onNext("2")        //Print: 2
}
  • 1. PublishSubject라는 Subject를 생성합니다.
  • 2. 이 때는 Observer가 없기 때문에 아무런 동작도 하지 않습니다.
  • 3. subscribe를 통해 observer를 생성해줍니다. (이 때 이전에 발행한 "Is anyone listening?" 값은 받을 수 없습니다. PublishSubject는 현재 존재하는 observer에게만 이벤트를 방출하기 때문입니다.)
  • 4. 1이 출력됩니다.
  • 5. 2가 출력됩니다. (cf. on(.next(_:))onNext(_:)는 같은 것입니다.)

이처럼 Subject는 외부로부터 값을 받고 이를 그대로 방출할 수 있습니다.

Subject의 종류

Subject에는 4가지 종류가 존재합니다.

PublishSubject

  • 초기값을 가지지 않고 새로운 값을 등록된 Subscriber에게 방출만하는 Subject입니다.
  • 구독되었을 때부터 새로운 이벤트를 수신하고 싶을 경우 사용합니다.
  • 위 그림처럼 각 Subscriber들은 구독 이후에 방출된 값들에 대해서만 수신이 가능합니다.
  • 단, completed와 error (완전 종료 이벤트)는 이후 구독한 Subscriber에게도 전달됩니다.
  • 시간이 민감한 데이터를 모델링할 때 유용합니다. 예를 들어 실시간 경매 앱이 존재한다고 했을 때 경매 시간이 끝난 이후에 들어온 유저에게 "경매 시간이 얼마남지 않았습니다!"와 같은 메세지를 전달하는 것은 매우 무의미합니다. PublishSubject 시간이 지나 구독을 시작한 Subscriber에게는 이벤트를 전달하지 않으므로, 무의미한 이벤트 전달을 하지 않을 수 있습니다.

BehaviorSubject

  • 하나의 초기값을 가진 상태로 시작하고 등록된 Subscriber에게 초기값 혹은 최신값을 방출하는 Subject입니다.
  • 마지막 .next 이벤트를 새로 등록된 Subscriber에게 반복한다는 점만 제외하면 PublisherSubject와 유사합니다.
  • 위 그림처럼 각 Subscriber는 구독하기 전에 방출된 값들부터 수신합니다.
  • completed와 error 이벤트(완전 종료 이벤트)가 발생한 이후에 새로 구독한 Subscriber가 있다면 해당 Subscriber에게도 정보가 전달됩니다.
  • 뷰를 가장 최신의 데이터로 채울 때 사용하기 좋습니다. 예를 들어 유저 프로필 화면을 BehaviorSubject를 통해 바인드해놓으면, 특정 값을 새롭게 가져오는 도중에도 초기값 혹은 최신값으로 화면을 항상 채워놓을 수 있습니다.

ReplaySubject

  • 버퍼를 두고 초기화를 진행하며, 버퍼 사이즈 만큼의 값들을 유지하면서 등록된 Subscriber에게 버퍼 내용 혹은 최신값을 방출하는 Subject입니다.
  • 위 그림처럼 새로운 Subscriber가 생기면 버퍼에 등록된 이벤트들을 그 Subscriber에게 방출합니다.
  • completed와 error 이벤트(완전 종료 이벤트)가 발생하면 새로 구독하는 Subscriber는 해당 이벤트만 수신합니다.
  • 주의할 점은 버퍼들이 모두 메모리에서 관리된다는 점입니다. 따라서 이미지나 Array같이 큰 사이즈의 데이터를 버퍼에 넣는 것은 지양해야 합니다.
  • 검색창같은 최근 내역을 필요로하는 데이터를 구현할 때 적절합니다. 최근에 저장된 값을 지속적으로 관리할 수 있습니다.

AsyncSubject

  • Subject가 Complete되면 가장 마지막에 존재하는 이벤트를 새로운 Subscriber에게 전달하는 Subject입니다.
  • 만약 가장 마지막 이벤트가 에러로 종료된다면 이벤트의 전달없이 에러만 출력됩니다.

참고

반응형