I am trying to better understand the Combine framework. AFAIK, .sink()
connects a publisher to a subscriber. In an Xcode Playground page, who exactly is the subscriber? Consider the following example:
PlaygroundPage.current.needsInfiniteExecution = true
var subscriptions: Set<AnyCancellable> = []
Timer.TimerPublisher(every: 1, on: .main, in: .common)
.autoconnect()
.sink { print($0) } // Who is this sink connecting the timer publisher to?
.store(in: &subscriptions)
I know the pub-sub link is taking place because the publisher does indeed start publishing. It is just unclear who the subscriber is. Is there a way to deterministically query Combine for who the subscriber is?
Also, if the subscriber of this timer publisher is the playgroundPage's current instance, then why do I have to store the subscription using store(in:)
? Shouldn't this be unnecessary since the subscriber is not going out of scope any time soon (not until I stop the playground)?
CodePudding user response:
Your understanding is wrong. .sink
is a subscriber — actually, it creates a Sink object, which is a subscriber — and in this case, it is the subscriber.
An added fine point is that an operator, such as .autoconnect()
, is both a subscriber and a publisher. But there is only one true subscriber at the end of this pipeline, and it is the Sink.
The Sink does not "connect the timer publisher" to anything. It itself is the object that is printing.
The .store
command assigns the Sink (wrapped up as an AnyCancellable) into the subscriptions
set. Note that this is a bad name: in Combine, a subscription is a very, very different thing from a subscriber.