在RAC3 / 4中组合冷信号

时间:2015-12-14 07:39:37

标签: reactive-cocoa reactive-cocoa-3

我希望有两个冷SignalProducer的B和C,它们都依赖于其他冷SignalProducer A,它会发出数据库实体对象 - 所以对我来说这对于完全相同的对象进行多播至关重要到达B和C.这是一些图表:

     --(transformations)--B
    /
-A ----(transformations)--C

但是因为B和C有一些转换,这可能需要大量的工作,我不希望它们在连接之前发生。

在RAC2中,我们[[RACSignal -publish] -autoconnect ]在这种情况下正常运作。

正如CHANGELOG所说,来自RAC2的多播使用startWithSignal变得更干净,但它1)立即开始,2)推动我在链的其余部分使用热信号

SignalProducer.buffer似乎是一个可以接受的解决方案。

在这种情况下,什么是正确的解决方案?

1 个答案:

答案 0 :(得分:0)

目前,我在RAC3 / Swift1.2中重新实现了RAC2中的-publish -autoconnect

func buffer<T, E>(capacity: Int) -> SignalProducer<T, E> -> SignalProducer<T, E> {
    return { (signal: SignalProducer<T, E>) -> SignalProducer<T, E> in

        let (buffer, bufferSink) = SignalProducer<T, E>.buffer(capacity)
        var connectionsCount = 0
        var upperDisposable: Disposable? = nil

        let addSubscriber: ()->() = {
            if (connectionsCount == 0) {
                upperDisposable = signal.start(bufferSink)
            }
            connectionsCount++
        }

        let removeSubscriber: ()->() = {
            connectionsCount--
            if connectionsCount == 0 {
                upperDisposable?.dispose()
                upperDisposable = nil
            }
        }


        return SignalProducer { (sink, disposable) in
            disposable.addDisposable(removeSubscriber)
            sendNext(sink, buffer)
            addSubscriber()
        }
        |> flatten(.Concat)
    }
}

它不是线程安全的,可能包含其他问题