[RxSwift] share() 연산자

Martin Kim·2022년 4월 28일
0

RxSwift

목록 보기
4/8
  • Observable의 create 클로저는 subscriber 가 설정될 때마다 호출된다.
  • 주의할 점은 subscribe(...)를 호출할 때마다 해당 subscribe에 대한 새로운 Observable이 생성되고 각 복사본이 이전과 동일하다는 보장이 없다는 것이다.
  • Observable은 매우 게으른 pull - driven 객체여서 subscribe가 설정되기 전까지는 아무런 동작을 하지 않는다.
  • 다시 말해, subscribe 클로저가 설정되면 → 그제서야 create 클로저가 호출된다. 즉, subscribe가 설정될 때마다 새로운 observable이 생성되는 것이다.
  • Observable을 공유하기 위해서는 share() 연산자를 사용한다. 이를 사용하면 같은 Observable에 subscribe를 해도 같은 observable 소스를 공유하게 된다.
  • share의 구현부를 살펴보자
    • replay: 버퍼의 크기를 설정한다.

    • scope: 버퍼의 생명주기를 지정한다.
      - .forever: Subscription이 0이 되더라도 버퍼가 유지. 그래서 새로운 Subscription은 Subscribe()를 하면 마지막에 버퍼에 남아있던 replay개수 만큼의 값을 수신.
      - .whileConnected: 1개 이상의 Subscriber가 존재하는 동안만 버퍼가 유지. Subscription이 0이 되면 버퍼가 비워지고 새로운 Subscription은 버퍼에 남아 있던 값이 없으므로 replay시 새 값을 요청해 수신.

      public func share(replay: Int = 0, scope: SubjectLifetimeScope = .whileConnected)
              -> Observable<Element> {
              switch scope {
              case .forever:
                  switch replay {
                  case 0: return self.multicast(PublishSubject()).refCount()
                  default: return self.multicast(ReplaySubject.create(bufferSize: replay)).refCount()
                  }
              case .whileConnected:
                  switch replay {
                  case 0: return ShareWhileConnected(source: self.asObservable())
                  case 1: return ShareReplay1WhileConnected(source: self.asObservable())
                  default: return self.multicast(makeSubject: { ReplaySubject.create(bufferSize: replay) }).refCount()
                  }
              }
          }
    • 코드를 보면 .forever이건, .whileConnected 이건 둘다 share(replay)를 호출하면 self.multicast(ReplaySubject.create(bufferSize: replay)).refCount() 를 반환한다. 즉, 사실 anObservable.share()anObservable.publish().refCount() 인 것이다.
      - publish() : 이 연산자는 보통의 Observable을 ConnectableObservable로 변환.
      - ConnectableObservable : ConnectableObservable은 Subscriber가 있어도 connect()를 호출하기 전까지는 아이템을 방출하지 않는다. connect()를 호출하고 나서야 아이템을 방출하기 시작한다.
      - refcount() : refcount() 는 ConnectableObservable에 Connect와 Disconnect를 자동으로 담당하고, ConnectableObservable을 보통의 Observable처럼 사용할 수 있게 해준다. 다시말해 Subscription count를 계속 세고 있다가 Subscription의 개수가 0 -> 1 개가 되는 시점에 connect()를 수행하고 Subscription이 0이 되면 disconnect()를 수행한다.

결론은 여러 시퀀스에서 접근해서 사용하게 되는 Observable은 Subscribe() 할때마다 subscription이 생성되니 share()해서 사용해야 한다. 보통 share(replay: 1) 형태로 사용한다.

출처:https://jusung.github.io/shareReplay/, Raywenderlich RxSwift

profile
학생입니다

0개의 댓글