combineLatest行为的差异Signal v SignalProducer(ReactiveCocoa 4)

时间:2016-03-07 11:19:01

标签: swift reactive-cocoa-4

我现在正在运行基本操作符,并且遇到了combineLatest运算符行为的差异。我不确定这是一个错误还是我无法理解信号和SignalProducers之间的差异。

let (numbersSig, numbersOb) = Signal<Int, NoError>.pipe()
let (lettersSig, lettersOb) = Signal<String, NoError>.pipe()
let signal = combineLatest(numbersSig, lettersSig)
signal.observeNext({value in print(value)})

numbersOb.sendNext(1)
lettersOb.sendNext("A")
lettersOb.sendNext("B")

产地: (1,&#34; A&#34;) (1,&#34; B&#34;)

但是,如果我使用SignalProducers编写我认为是等效代码的内容:

let numberProducer = SignalProducer<Int, NoError> { (observer, disposable) in
    for v in [1] { observer.sendNext(v) }
}

let letterProducer = SignalProducer<String, NoError> { (observer, disposable) in
    for v in ["A", "B", "C", "D"] { observer.sendNext(v) }
}

let combinedProducer = combineLatest(numberProducer, letterProducer)
combinedProducer.on(next: {value in print(value) }).start()

输出: (1,&#34; D&#34;)

我故意将observer.sendCompleted()从SignalProducers中移出,因为我认为这是负责任的,但事实并非如此。我错过了什么?

2 个答案:

答案 0 :(得分:0)

是的,这似乎是一个错误。你介意在Github回购中打开一个问题,以便我们可以看一下吗?更好的是,如果您可以通过失败的测试打开PR,那将是非常棒的! :)

我检查可能是变通方法的内容:如果您使用startWithNext而不是on + start,会得到相同的结果吗?

答案 1 :(得分:0)

感谢NachoSoto的建议。我尝试了你建议的替代方法,输出没有变化。当我在Github回购中发布这个问题时,我从芳香(Brian Thomas)那里得到了以下答案:

  

在combinedProducer上调用start处理调用start   内部字母和数字生成者(具体见liftRight in   SignalProducer.swift,其中当otherProducer.startWithSignal的时候   closure返回它将运行你的sendNext代码)。因为他们是   同步信函生产者只是“更新”它的所有价值   在数字生产者开始返回值之前。你可以测试一下   通过在生产者的combineLatest方法调用中反转它们   例。如果你想获得第一个的“推送值”行为   试试

let (numbersSig, numbersSink) = Signal<Int, NSError>.pipe()
let (lettersSig, lettersSink) = Signal<String, NSError>.pipe()
let numberProducer = SignalProducer(signal: numbersSig)
let letterProducer = SignalProducer(signal: lettersSig)

let combinedProducer = combineLatest(numberProducer, letterProducer)
combinedProducer.on(next: {value in print(value) }).start()

lettersSink.sendNext("A")
numbersSink.sendNext(1)
lettersSink.sendNext("B")
numbersSink.sendNext(2)
lettersSink.sendNext("C")

我按照他的建议尝试颠倒numberProducer和letterProducer,输出确实和我最初使用Signals一样。

let numberProducer = SignalProducer<Int, NoError> { (observer, disposable) in
    for v in [1] { observer.sendNext(v) }
}

let letterProducer = SignalProducer<String, NoError> { (observer, disposable) in
    for v in ["A", "B", "C", "D"] { observer.sendNext(v) }
}

let combinedProducer = combineLatest(letterProducer, numberProducer)
combinedProducer.startWithNext {value in print(value)}

产地: (“A”,1) (“B”,1) (“C”,1) (“D”,1)

您是否仍然认为这是一个错误或实施行为?