查找已取消的发布商组合

Find Canceled Publisher Combine

我正在尝试使用 combine 来管理我的套接字和处理消息

private var garbageBag = Set<AnyCancellable>()

func setupSocket() {
  
    
    SocketHelper.shared.startListene()
  
    garbageBag.forEach{[=10=].cancel()}
    
    SocketHelper.shared.publisher.sink {[unowned self] (sub) in
        print(sub)
        print("FINISH ")

    } receiveValue: {[unowned self] (value) in
        print("SUBSCRBE GOT VALUE ")
      
     }.store(in: &garbageBag)

}

这个方法调用了几次,所以sink也调用了很多次,防止我写成like,解决了问题

    garbageBag.forEach{[=11=].cancel()}

但是现在假设此方法将被调用 4 次,因此在 garbageBag 中将有 4 个项目

如何删除已取消的商品

我知道直接清空 Set 是一种解决方案,但是有什么方法可以检查吗?

无法检查 AnyCancellable 是否处于活动状态。 Cancellable(其类型擦除形式 AnyCancellable 是)只需要一个 cancel() 方法,协议没有状态处理要求。

然而,Cancellable 在它被释放时调用 cancel,所以在 Combine 中处理订阅的最好方法是在你想取消时丢弃对 AnyCancellable 实例的所有引用一个订阅。

因此,对于您的特定用例,最好的方法是只保留一个 AnyCancellable 实例,因为对同一发布者进行多个订阅可能无论如何都没有多大意义。

您可以决定在后续调用 setupSocket 时是要创建新订阅,还是什么都不做并保持前一个订阅有效(不过,我建议您做后者,因为您使用套接字)。

private var socketSubscription: AnyCancellable?

func setupSocket() {
    // We only want 1 subscription
    guard socketSubscription == nil else { return }
    
    SocketHelper.shared.startListene()
    
    socketSubscription = SocketHelper.shared.publisher.sink {[unowned self] (sub) in
        print(sub)
        print("FINISH ")
     } receiveValue: {[unowned self] (value) in
        print("SUBSCRBE GOT VALUE ")
     }
}