값(value)으로 보다는 참조(reference)로 publisher를 공유할 수 있게 해줍니다.
즉, share() 메서드는 일반적으로 struct로 되어있는 Publisher를 reference타입으로 반환해줌!
subscriber는 구독후에 upstream publisher가 방출하는 값을 받게됩니다. subscriber가 upstream publisher가 완료된 공유 publisher를 구독하면, 해당 subscriber는 완료 이벤트(completion event)만 받습니다.
import Combine
import Foundation
let shared = URLSession.shared
.dataTaskPublisher(for: URL(string: "https://www.raywenderlich.com")!)
.map(\.data)
.print("shared")
.share()
print("subscribing first")
let subscription1 = shared
.sink(receiveCompletion: { _ in },
receiveValue: { print("subscription1 received: '\($0)'") }
)
print("subscribing second")
let subscription2 = shared
.sink(receiveCompletion: { _ in },
receiveValue: { print("subscription2 received: '\($0)'") }
)
//subscribing first
//shared: receive subscription: (DataTaskPublisher)
//shared: request unlimited
//subscribing second
//shared: receive value: (266289 bytes)
//subscription1 received: '266289 bytes'
//subscription2 received: '266289 bytes'
//shared: receive finished
• 첫번째 구독 subscription1이 DataTaskPublisher 를 실행시킵니다. • 두번째 구독 subscription2에서 바뀐게 없이 publisher를 계속 실행. 두번째 요청은 하지않음. • request가 끝나면, publisher가 두 구독자 (subscription1, subscription2)에게 데이터 결과값을 방출한후 완료됩니다.
한줄요약: share() 를 사용하면, subscriber가 여럿 있어도 요청을 한번만 보내고 결과값은 다같이 받습니다.
share()의 역할을 확인해보기 위해, 위 예제코드에 share() 메서드를 주석 처리해보고 결과값을 보면