RxSwift:
share(replay:scope:)
사용 목적과 부작용 정리
share(replay:scope:)
는 Cold Observable을 Hot Observable로 변환하며, 캐시와 구독 공유 기능을 제공! 하지만 주의해야 할 부작용과 주의사항에 더 자세히 공부하기위해 내용 작성!
목적 요약
목적 |
설명 |
구독 공유 |
여러 구독자 간에 Observable 실행을 공유 (side effect 방지) |
캐싱 |
replay 파라미터를 통해 이벤트 재전송 |
리소스 절약 |
API 호출 등 무거운 작업을 한 번만 실행 |
Cold → Hot 변환 |
Cold Observable을 Hot으로 바꿔 여러 구독자가 공유 가능 |
사용 예시
1 2 3 4 5 6 7 8 9 10 11
| let shared = source .map { heavyComputation($0) } .share(replay: 1, scope: .forever)
shared .subscribe(onNext: { print("🔵 First: \($0)") }) .disposed(by: self.disposeBag)
shared .subscribe(onNext: { print("🔴 Second: \($0)") }) .disposed(by: self.disposeBag)
|
heavyComputation()
은 한 번만 실행됨
- 두 구독자가 동일한 값 공유
scope:
파라미터
값 |
설명 |
.whileConnected |
최소 1개의 구독자가 있을 때만 구독 유지 |
.forever |
구독자가 없어도 내부 스트림 계속 유지됨 (메모리 캐시됨) |
부작용 및 주의사항
부작용/위험 요소 |
설명 |
메모리 누수 가능성 |
replay > 0 또는 .forever 일 경우 캐시된 이벤트가 계속 메모리에 남음 |
의도치 않은 공유 |
모든 구독자가 같은 값을 받기 때문에, 독립적인 흐름이 필요한 경우 적합하지 않음 |
내부 로직 숨김 |
side effect가 숨겨져 디버깅이 어려워질 수 있음 |
초기 구독 타이밍 중요 |
.whileConnected 는 구독자가 생기기 전에는 실행되지 않음 |
subscribe 시점 제어 어려움 |
share() 이후의 스트림 타이밍 제어가 어려울 수 있음 |
상황 추천
상황 |
사용 추천 여부 |
여러 구독자가 동일한 데이터를 원할 때 |
✅ 사용 |
API 호출, 상태 캐시 필요 시 |
✅ 사용 |
각 구독자가 독립적으로 실행돼야 할 때 |
❌ 사용 X |
메모리 관리가 중요한 상황 |
⚠️ 주의해서 사용 (특히 .forever ) |
요약
share(replay:scope:)
는 Hot + 캐시 + 공유를 동시에 제공
- 중복 실행 방지와 성능 최적화에 매우 유용
- 하지만 잘못 사용하면 메모리 누수, 비의도적 공유, 디버깅 어려움 유발 가능
적절한 시점과 메모리 범위 내에서 사용하는 것이 중요!!!!!