简体   繁体   English

RAC3 / 4中冷信号的组播

[英]Multicasting of cold signals in RAC3/4

I want to have two cold SignalProducer s B and C, both of them depends on other cold SignalProducer A, which emits db entity objects — so it's critical for me to multicast so exactly same object arrive to both B and C. Here is some graph: 我想要两个冷的SignalProducer的B和C,它们都依赖于另一个冷的SignalProducer A,后者发出db实体对象-因此,对我来说组播非常重要,因此完全相同的对象同时到达B和C。 :

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

But because B and C has some transformations, which may require significant amount of work, I don't want them to happen until they are connected. 但是由于B和C进行了某些转换,可能需要大量工作,所以我不希望它们在连接之前发生。

In RAC2 we had [[RACSignal -publish] -autoconnect ] which worked ok in this case. 在RAC2中,在这种情况下, [[RACSignal -publish] -autoconnect ]可以正常工作。

As CHANGELOG says, multicasting from RAC2 made cleaner with startWithSignal , but it 1) starts immediately, 2) pushes me to use hot signal all over the rest of the chain 就像CHANGELOG所说的那样,使用startWithSignal从RAC2进行的多播更加startWithSignal ,但它1)立即开始,2)促使我在整个链的其余部分使用热信号

SignalProducer.buffer seems so be an acceptable solution. SignalProducer.buffer似乎是可以接受的解决方案。

What is the proper solution in this case? 在这种情况下正确的解决方案是什么?

Currently I reimplemented -publish -autoconnect from RAC2 in RAC3/Swift1.2 like that: 目前,我在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)
    }
}

It's not thread safe and probably can contain other issues 它不是线程安全的,可能包含其他问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM