RxSwift

[RxSwift] Relay

thoonk: 2024. 3. 11. 14:27
반응형

Relay

  • Subject Wrapping 하여 기능 확장
  • Subject 와 유사하지만 Next 이벤트만 발생하며, Completed 와 Error 이벤트는 발생하지 않음.→ 스트림이 계속 유지되어 UI Event 와 바인딩하여 사용하기 적합
  • Dispose() 호출되어야 메모리 해제
  • RxCocoa 임포트 필수
  • .accept 로 데이터 방출
  • PublishRelay 또는 BehaviorRelay 는 기존 PublishSubject 와 BehaviorSubject 를 Wrapping 한 것으로 기존 개념은 Publish 와 Relay 차이 말고는 같은 방식

Subject 대신 Relay 를 사용하는 이유

  • Subject 는 메모리 관리가 명확하지 않아 메모리 누수가 발생할 가능성이 있지만 Relay 는 Dispose() 메서드를 통해 명확하게 메모리를 해제할 수 있음.
  • Subject 는 구독 시점에 따라 이전에 방출된 데이터를 받을 수 있지만 Relay 는 구독 시점에 관계없이 특정 시점 이후의 데이터만 받을 수 있음.
  • Subject 는 완료 또는 에러 이벤트를 발생시키지만 Relay는 발생시키지 않아 UI Event에 적합함

Relay 종류

PublishRelay

  • 비어있는 상태로 구독 이후 받은 이벤트를 방출함.

활용 예시

  • 실시간 데이터 스트림을 구현할 때
  • 사용자 입력 데이터를 처리할 때

코드

// PublishRelay 예시
let relay = PublishRelay<Int>()

// 구독 1
relay.subscribe(onNext: { value in
  print("구독 1:", value)
})

// 값 방출
relay.accept(1)
// 구독 1: 1

// 구독 2
relay.subscribe(onNext: { value in
  print("구독 2:", value)
})

// 값 방출
relay.accept(2)

// 구독 1: 2
// 구독 2: 2

BehaviorRelay

  • 초기 값을 가진 상태로, 새로운 구독자에게 초기 값 또는 최신 값을 방출함.
  • 추가적으로, 현재 값(element)에 접근할 수 있음.

활용 예시

  • 사용자 설정을 저장할 때
  • 화면 상태를 유지할 때

코드

// BehaviorRelay 예시
let relay = BehaviorRelay<String>(value: "초기값")

// 구독 1
relay.subscribe(onNext: { value in
  print("구독 1:", value)
})

// 값 변경
relay.accept("새로운 값")
// 구독 1: 초기값
// 구독 1: 새로운 값

// 구독 2
relay.subscribe(onNext: { value in
  print("구독 2:", value)
})
// 구독 2: 새로운 값

print(relay.value) // 새로운 값

ReplayRelay (RxSwift6 추가)

  • 버퍼 사이즈만큼 최신 이벤트를 유지하면서 새로운 구독자에게 방출함.

활용 예시

  • 로그 기록을 관리할 때
  • 과거 데이터를 분석할 때

코드

// ReplayRelay 예시
let relay = ReplayRelay<Int>(bufferSize: 2)

// 값 방출
relay.accept(1)
relay.accept(2)
relay.accept(3)

// 구독 1
relay.subscribe(onNext: { value in
  print("구독 1:", value)
})

// 값 방출
relay.accept(4)

// 구독 2
relay.subscribe(onNext: { value in
  print("구독 2:", value)
})

/*
구독 1: 2
구독 1: 3
구독 1: 4
구독 2: 3
구독 2: 4
*/

 

부족한 점 피드백해주시면 감사합니다 :)

반응형