Swift 如何在Combine中将subscrber与主题分离?

Swift 如何在Combine中将subscrber与主题分离?,swift,combine,Swift,Combine,我正在编写一个程序,需要动态地从事件源附加/分离事件处理程序。 这种情况会发生很多次,我不希望附加/分离导致任何消息丢失或重复 但我似乎在这里做错事来分离联合收割机订户 import Foundation import Combine let a = PassthroughSubject<String,Never>() var b = a .buffer(size: .max, prefetch: .byRequest, whenFull: .customError({ f

我正在编写一个程序,需要动态地从事件源附加/分离事件处理程序。 这种情况会发生很多次,我不希望附加/分离导致任何消息丢失或重复

但我似乎在这里做错事来分离联合收割机订户

import Foundation
import Combine

let a = PassthroughSubject<String,Never>()
var b = a
    .buffer(size: .max, prefetch: .byRequest, whenFull: .customError({ fatalError() }))
    .receive(on: DispatchQueue.main)
    .sink(receiveValue: { print($0) })
a.send("AAA")
b.cancel()
a.send("BBB")
b = a
    .buffer(size: .max, prefetch: .byRequest, whenFull: .customError({ fatalError() }))
    .receive(on: DispatchQueue.main)
    .sink(receiveValue: { print($0) })
a.send("CCC")
RunLoop.main.run()
CCC
重复,而
BBB
意外。它看到SMS取消
b
不会将其与源
a
分离。看来我做这些事情完全错了

什么是从主题附加/分离订阅者的正确方法?在这种情况下,我希望动态地从
a
附加/分离
b

  • Xcode 11 GM

我不认为你做错事的速度太快。我的猜测是,当创建第二条管道时,第一条管道并没有消失。您可以通过在两个print语句中添加一些额外的文本来证明这一点。cancel()的文档没有说明它何时生效。您可以尝试将nil分配给b,而不是调用cancel()。我想你需要把b定义为任何可取消的?“那样的话,”迈克尔·萨尔蒙我同意你的猜测。即时和动态连接/分离能力(正确处理这种情况)是我的程序的要求。如果联合收割机不是为支持这种情况而设计的,我就是不能依赖它。在完全放弃它之前,我会尝试使用nil。@MichaelSalmon我尝试将它设置为nil,得到了相同的结果。无论如何,谢谢你的欢呼。
AAA
BBB
CCC
CCC