본문 바로가기

개발

RxSwift Subjects

728x90

RxSwift Subjects는 다양한 시나리오에서 유용한 도구입니다. Observables와 비슷한 방식으로 값을 방출하지만, Subjects는 다음과 같은 특별한 기능을 제공합니다.

1. 값 발행 및 이벤트 처리:

import RxSwift



let subject = PublishSubject<String>()



subject.onNext("Hello")

subject.onNext("World!")

subject.onNext("RxSwift")



subject.subscribe(onNext: { message in

  print("Received message: \(message)")

})
  • subject는 String 값을 방출하는 PublishSubject입니다.
  • onNext메서드를 사용하여 값을 발행합니다.
  • subscribe메서드를 사용하여 방출된 값을 구독합니다.

2. 백플로우 제어:

import RxSwift



let subject = BehaviorSubject<String>(value: "Initial Value")



subject.onNext("Hello")

subject.onNext("World!")



subject.subscribe(onNext: { message in

  print("Subscriber 1: \(message)")

})



subject.onNext("RxSwift")



subject.subscribe(onNext: { message in

  print("Subscriber 2: \(message)")

})

 

  • subject는 초기 값 "Initial Value"를 가진 BehaviorSubject입니다.
  • onNext메서드를 사용하여 값을 발행합니다.
  • 두 개의 Subscriber가 구독합니다.
  • 첫 번째 Subscriber는 발행된 모든 값을 받습니다.
  • 두 번째 Subscriber는 구독 후에 발행된 값만 받습니다.

3. ReplaySubject를 사용한 이전 값 접근:

import RxSwift



let subject = ReplaySubject<String>(bufferSize: 2)



subject.onNext("Hello")

subject.onNext("World!")

subject.onNext("RxSwift")



subject.subscribe(onNext: { message in

  print("Subscriber 1: \(message)")

})



subject.subscribe(onNext: { message in

  print("Subscriber 2: \(message)")

})

 

  • subject는 버퍼 크기 2인 ReplaySubject입니다.
  • onNext메서드를 사용하여 값을 발행합니다.
  • 두 개의 Subscriber가 구독합니다.
  • 첫 번째 Subscriber는 발행된 모든 값을 받습니다.
  • 두 번째 Subscriber는 구독 후에 발행된 두 개의 값만 받습니다.

4. PublishSubject를 사용한 Single Event Notification:

import RxSwift



let subject = PublishSubject<String>()



subject.onNext("Hello")

subject.onNext("World!")



subject.subscribe(onNext: { message in

  print("Received message: \(message)")

})



// 새로운 Subscriber는 이전 값을 받지 못합니다.

subject.onNext("RxSwift")



subject.subscribe(onNext: { message in

  print("New Subscriber: \(message)")

})

 

  • subject는 PublishSubject입니다.
  • onNext메서드를 사용하여 값을 발행합니다.
  • 첫 번째 Subscriber는 발행된 첫 번째 값 "Hello"만 받습니다.
  • 두 번째 Subscriber는 구독 후에 발행된 "RxSwift" 값만 받습니다.

5. RefCountSubject를 사용한 리소스 관리:

import RxSwift



let subject = RefCountSubject<String>()



subject.onNext("Hello")

subject.onNext("World!")



let subscription1 = subject.subscribe(onNext: { message in

  print("Subscriber 1: \(message)")

})



subject.onNext("RxSwift")



let subscription2 = subject.subscribe(onNext: { message in

  print("Subscriber 2: \(message)")

})



// 구독자가 없으면 Subject가 종료됩니다.

subscription1.dispose()

subscription2.dispose()

 

  • subject는 RefCountSubject입니다.
  • onNext메서드를 사용하여 값을 발행합니다.
  • 두 개의 Subscriber가 구독합니다.
  • 첫 번째 Subscriber는 발행된 모든 값을 받습니다.
  • 두 번째 Subscriber는 구독 후에 발행된 두 개의 값만 받습니다.
  • 두 Subscriber 모두 dispose()되면 Subject가 종료됩니다.

6 CustomSubject 클래스 구현:

import RxSwift



class CustomSubject: Subject<String> {

  private var subscribers: [AnyCancellable] = []

  private var currentValue: String?



  func onNext(_ element: String) {

    // 발행된 값을 저장

    currentValue = element



    // 구독자들에게 값을 전달

    for subscriber in subscribers {

      subscriber.onNext(element)

    }

  }



  func subscribe<S: Subscriber>(subscriber: S) -> Subscription {

    // 구독자 추가

    subscribers.append(subscriber.subscribe(onNext: { [weak self] element in

      guard let self = self else { return }

      // 값 변경 시에만 onNext 호출

      if self.currentValue != element {

        subscriber.onNext(element)

      }

    }, onError: subscriber.onError, onCompleted: subscriber.onCompleted))



    // 구독 해제 시 처리

    return Disposables.create {

      [weak self] in

      guard let self = self else { return }

      self.subscribers.removeAll { $0 === subscriber }

    }

  }

}

 

6.1. CustomSubject 사용 예시:

import RxSwift



let customSubject = CustomSubject()



customSubject.onNext("Hello")

customSubject.onNext("World!")



customSubject.subscribe(onNext: { message in

  print("Subscriber 1: \(message)")

})



customSubject.onNext("RxSwift") // 두 번째 Subscriber는 이전 값을 받지 않음



customSubject.subscribe(onNext: { message in

  print("Subscriber 2: \(message)")

})

 

설명:

  • CustomSubject 클래스는 Subject 프로토콜을 구현합니다.
  • onNext메서드는 발행된 값을 저장하고 구독자들에게 전달합니다.
  • subscribe메서드는 구독자를 추가하고 구독 해제 시 처리를 정의합니다.
  • CustomSubject는 발행된 값이 변경된 경우에만 onNext을 호출하여 중복값을 방지합니다.
  • 예시 코드에서 첫 번째 Subscriber는 발행된 모든 값을 받지만, 두 번째 Subscriber는 마지막 값만 받습니다.

참고:

  • CustomSubject는 특정 로직이나 제약을 필요로 하는 상황에서 유용합니다.
  • 기본적인 Subject 기능 외에 원하는 동작을 추가하여 사용자 정의할 수 있습니다.
  • RxSwift 공식 문서: 한국어: https://github.com/ReactiveX/RxSwift

'개발' 카테고리의 다른 글

RxSwift Filtering Operators  (0) 2024.07.09
RxSwift Observables and Subjects  (0) 2024.07.09
RxSwift Observables  (0) 2024.07.09
RXSwift의 요소  (0) 2024.07.09
RxSwift의 개념  (0) 2024.07.09