【问题标题】:Find Canceled Publisher Combine查找已取消的发布者组合
【发布时间】:2021-04-15 22:53:35
【问题描述】:

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

private var garbageBag = Set<AnyCancellable>()

func setupSocket() {
  
    
    SocketHelper.shared.startListene()
  
    garbageBag.forEach{$0.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{$0.cancel()}

但是现在假设这个方法会被调用 4 次,所以在 garbageBag 中会有 4 个项目

如何删除已取消的项目

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

【问题讨论】:

  • 同时对同一个发布者进行多个订阅实际上是否有效?如果没有,为什么不将AnyCancellable 存储在一个变量中,并在再次调用setupSocket 时覆盖它?
  • @DávidPásztor 是的,这很好! ,我的问题是AnyCancellablecancel() 那么我怎么知道它是否被取消?有什么办法

标签: swift combine


【解决方案1】:

无法检查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 ")
     }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    相关资源
    最近更新 更多