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