본문 바로가기
iOS📱/RxSwift

[RxSwift] Share(replay:)

by 텅빈비니 2024. 1. 25.
반응형

안녕하세요🐶

빈지식 채우기의 비니🙋🏻‍♂️입니다.

 

오늘은 Share 에 대해 알아보도록 하겠습니다.

.

Share에 대해 알아보기 전!

Observable의 간단한 특징 하나만 보고 가도록 하겠습니다.

.

- Observable은 Subscribe 될때마다 Create을 호출해 Observable을 생성합니다.

- Observable은 Subscribe를 한 횟수만큼 Subscription 시퀀스를 생성됩니다.

.

.

이러한 사실을 기억하고 Share에 대해 알아보도록 하겠습니다.


1. Share

1-1. Share 사용 X

바로 소스를 통해 확인하도록 하겠습니다.

[ 코드 ]

// API 요청이라고 가정
let reqAPI = Observable.of(100).debug("reqAPI(No Share)")
        
let result = noShareBtn.rx.tap	// 버튼 이벤트
    .flatMap { _ in
        reqAPI
    }

result
    .map { element in
        element > 0
    }
    .bind(to: noShareBtn.rx.isHidden)
    .disposed(by: disposeBag)

result
    .map { element in
        "Count : \(element)"
    }
    .bind(to: noShareLabel.rx.text)
    .disposed(by: disposeBag)

- 버튼을 누르면 API 요청을 보내 결과를 받고, 그 결과를 통해 버튼을 감추거나 문구를 표시합니다.

 

[ 실행 결과 ]

위 결과와 같이 API를 두번 요청하여 결과를 받았습니다.

2번 이상의 API 요청이 있을 시 Observable 시퀀스가 계속해서 늘어간게 되는 문제점이 있습니다.


1-2. Share 사용 O

위와 똑같은 예제에 Share를 추가하여 확인해보도록 하겠습니다.

[ 코드 ]

let reqAPI = Observable.of(100).debug("reqAPI(Yes Share)")
        
let result = shareBtn.rx.tap
    .flatMap { _ in
        reqAPI
    }
    .share()		// Share 사용

result
    .map { element in
        element > 0
    }
    .bind(to: shareBtn.rx.isHidden)
    .disposed(by: disposeBag)

result
    .map { element in
        "Count : \(element)"
    }
    .bind(to: yesShareLabel.rx.text)
    .disposed(by: disposeBag)

[ 실행 결과 ]

Share를 사용함으로써 한번의 API 호출이 이루어졌음을 확인할 수 있습니다.

 


2. 정리

  1. Share은 Subscribe가 처음 호출될 때만 Subscription을 생성.
  2. 이후에 Subscribe가 호출되면 이미 만들어진 Subscription을 공유
  3. Share에 있는 Subscribe 모두가 Dispose 되면 모든 Subscription Dispose
  4. Share은 Completed 되지 않는 Observable에 사용하는 것이 안전

이상으로 Share에 대해 알아보았습니다.

전체 소스는 아래에 있습니다.

더보기

func setYESShare() {

        let reqAPI = Observable.of(100).debug("reqAPI(Yes Share)")

        

        let result = shareBtn.rx.tap

            .flatMap { _ in

                reqAPI

            }

            .share()

        

        result

            .map { element in

                element > 0

            }

            .bind(to: shareBtn.rx.isHidden)

            .disposed(by: disposeBag)

        

        result

            .map { element in

                "Count : \(element)"

            }

            .bind(to: yesShareLabel.rx.text)

            .disposed(by: disposeBag)

    }

    

    func setNoShare() {

        let reqAPI = Observable.of(100).debug("reqAPI(No Share)")

        

        let result = noShareBtn.rx.tap

            .flatMap { _ in

                reqAPI

            }

        

        result

            .map { element in

                element > 0

            }

            .bind(to: noShareBtn.rx.isHidden)

            .disposed(by: disposeBag)

        

        result

            .map { element in

                "Count : \(element)"

            }

            .bind(to: noShareLabel.rx.text)

            .disposed(by: disposeBag)

    }

감사합니다~~


참고

반응형

'iOS📱 > RxSwift' 카테고리의 다른 글

[RxSwift] Traits ( Single, Maybe, Completable )  (0) 2024.01.18
[RxSwift] Debounce, Throttle  (0) 2024.01.17
[RxCocoa] Driver  (0) 2024.01.17
[RxCocoa] Relay  (2) 2024.01.16
[ RXSwift ] Subject  (2) 2024.01.15