问题描述
合并订阅示例代码段均将结果订阅存储到subscriptions
集
private var subscriptions = Set<AnyCancellable>()
我们为什么需要这样做?
future
.sink(receiveCompletion: { print($0) },receiveValue: { print($0) })
.store(in: &subscriptions)
解决方法
我们通常希望将订阅存储在某处,以保持订阅有效。我们通常希望保持几个订阅状态,直到封闭对象被破坏为止,因此将所有订阅存储在单个容器中很方便。
但是,容器不是必须必须是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($0) },receiveValue: { print($0) })
.store(in: &tickets)
,
Cancellable
是Combaine提供的协议。
订阅代码(例如发布者,运营商,订阅者调用链)返回一个Cancellable
对象,以允许手动取消订阅,并且当对象从内存中释放时,它会取消整个订阅并从中释放其资源记忆。
为实现释放过程的自动化,wen可以将多个订阅存储在AnyCancellable
集合中,因此当集合将被取消初始化时,内部的所有订阅都将被取消,相关资源将被释放。
AnyCancellable
是一种类型擦除类型,允许将不同的可取消类型存储在同一集合中。
参考
store(in:)
将可擦除类型的可取消实例存储到指定的集合中。