What is the reason to store subscription into a subscriptions set?

Viewed 812

Combine subscription sample code snippet all store the resulting subscription into the subscriptions set

private var subscriptions = Set<AnyCancellable>()

Why do we need to do it?

future
  .sink(receiveCompletion: { print($0) }, receiveValue: { print($0) }) 
  .store(in: &subscriptions)
2 Answers

We usually want to store the subscription somewhere, to keep the subscription alive. We often want to keep several subscriptions alive until the enclosing object is destroyed, so it's convenient to store all the subscriptions in a single container.

However, the container does not have to be a Set! It can be (and usually should be) an Array.

Cancellable provides two store(in:) methods:

extension Cancellable {
    public func store<C>(in collection: inout C) where C : RangeReplaceableCollection, C.Element == AnyCancellable

    public func store(in set: inout Set<AnyCancellable>)
}

(Array conforms to RangeReplaceableCollection, but Set does not, so it needs its own method.)

You have found the one that stores into a Set. But do you need the behavior of a Set? The only reason to store your subscriptions in a Set is if you need to efficiently remove a single subscription from the set, and the set may be large. Otherwise, just use an Array, like this:

class MyObject {

    private var tickets = [AnyCancellable]()

    ...
        future
            .sink(receiveCompletion: { print($0) }, receiveValue: { print($0) }) 
            .store(in: &tickets)

Cancellable is a protocol provided by Combaine.

The subscription code (e.g. publisher, operators, subscriber call chain) return a Cancellable object to allow manual cancelation for a subscription and when the object is released from memory, it cancels the whole subscription and release its resources from memory.

To automate the releasing process, wen can store multiple subscriptions in AnyCancellable collection, so when the collection is about to be deinitialized all subscriptions inside would be canceled and associated resources would be released.

AnyCancellable is a type-erased type to allow storing different cancelable types to be stored inside the same collection.

REFERENCE

store(in:) stores the type-erasing cancellable instance into a specified set.

Related