How does a Combine Publisher store a subscriber

I know Combine is a proprietary Apple framework. But my question is about general code.
So consider the Publisher protocol. It has a func receive<S>(subscriber: S) by with a subscriber can subscribe.
It is the subscriber that has the the receive method, that the publisher uses or delegates (I understand) to send values over time.

Great! Except, publishers are generally value types, aka structs. Since, the receive method is not declared mutating, this must mean the publisher cannot store a reference to the subscriber.
But the, how does it send values to it?


1 Like

A Publisher’s implementation of receive(subscriber:) must create a subscription object (conforming to protocol Subscription) and pass it to the subscriber’s method receive(subscription:). Every call to the Publisher’s receive(subscriber:) must create a new subscription object; subscription objects cannot be reused.

It is the subscription object that holds the reference to the Subscriber.

A cold Publisher (examples: Just, Publishers.Sequence, URLSession.DataTaskPublisher) doesn’t need to keep its own reference to the subscription or to the Subscriber, because the subscription object can contain everything it needs to deliver values and completion to the Subscriber.

A hot Publisher (examples: Subject, Future, NotificationCenter.Publisher, NSObject.KeyValueObservingPublisher) does need to keep a reference to the subscription object, and so a hot Publisher is implemented either as a class, or as a struct that privately holds a reference to a class instance.

1 Like

Sweet! Thanks Rob!

Would you care to talk a little more on the role of the Subscription? I mean, I highly value your opinions, and I take them as such, just curious what you think.

Why not just have a publisher/subscriber model? I seems like the subscription component can be highly important and even take the heavy load of actually producing the values themselves?