将订阅存储到订阅集中的原因是什么?

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

合并订阅示例代码片段全部将生成的订阅存储到subscriptions集合

private var subscriptions = Set<AnyCancellable>()

为什么我们需要这样做?

future
  .sink(receiveCompletion: { print([=11=]) }, receiveValue: { print([=11=]) }) 
  .store(in: &subscriptions)

Cancellable是Combaine提供的协议。

订阅代码(例如发布者、运营商、订阅者调用链)return一个Cancellable允许手动取消订阅的对象,当对象从内存中释放时,它会取消整个订阅并从内存中释放其资源。

为了自动化释放过程,我们可以在AnyCancellable集合中存储多个订阅,这样当集合即将被取消初始化时,其中的所有订阅将被取消,相关资源将被释放。

AnyCancellable 是一个 type-erased 类型,允许在同一个集合中存储不同的可取消类型。

参考资料

store(in:) 将 type-erasing 可取消实例存储到指定集合中。

我们通常希望将订阅存储在某处,以使订阅保持活动状态。我们经常希望在封闭对象被销毁之前让多个订阅保持活动状态,因此将所有订阅存储在一个容器中很方便。

但是,容器并非必须是Set!它可以是(通常应该是)Array.

Cancellable提供两种store(in:)方法:

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符合RangeReplaceableCollection,但Set不符合,所以需要自己的方法。)

您找到了存储到 Set 中的那个。但是你需要 Set 的行为吗?将订阅存储在 Set 中的唯一原因是,如果您需要有效地从集合中删除单个订阅,并且集合可能很大。否则,只需使用 Array,像这样:

class MyObject {

    private var tickets = [AnyCancellable]()

    ...
        future
            .sink(receiveCompletion: { print([=11=]) }, receiveValue: { print([=11=]) }) 
            .store(in: &tickets)