I feel like I understand all of the basic components of ReactiveCocoa (conceptually), by understanding how to connect all of the pieces together is still a bit confusing.
For example, after reading about Signal, I fully expected SignalProducer to just have one start() method which returned a Signal, which you would use like so:
mySignalProducer.start().observe(myObserver)
Instead, you have to pass an observer into start(), and SignalProducer calls observe() for you:
mySignalProducer.start(myObserver)
This means that the interface of SignalProducer is much larger (more to understand), because all of the variations on observe() have to be duplicated on start() (e.g. startNext(), etc).
I think there are two possibilities here:
- There are technical reasons why start() can't simply return a Signal
- I misunderstand the SignalProducer conceptually, leading to wonky expectations of its interface
If 1 is the case, I'm guessing that has something to do with memory management and disposables which I don't fully understand yet.
I'm more worried that 2 is the case. Internally, my understanding of SignalProducer is basically mapped to the concept of a Factory, e.g.:
mySignalFactory.createSignal().observe(myObserver)
which is why I'm surprised we don't find a start() which returns a Signal.
I would be hugely appreciative if the community could shed some light here.
Thanks!
I think the main reason is some events can be sent immediately when the producer starts.
For example, if you don't like the start series interface, and want to get a signal directly when start:
extension SignalProducer {
func getSignalFromStart() -> Signal<Value, Error> {
var signal: Signal<Value, Error>!
startWithSignal{ innerSignal, _ in
signal = innerSignal
}
return signal
}
}
Then you can miss some events. Try this:
// When property.producer starts, it will send its current value immediately
let property = MutableProperty(1)
property.producer.getSignalFromStart().observeValues { value in
print("getSignalFromStart \(value)") // maybe not what you want, only gets 2
}
property.producer.startWithValues { value in
print("normal start \(value)") // this normally gets 1 and 2
}
property.value = 2
来源:https://stackoverflow.com/questions/35616530/why-doesnt-signalproducer-return-a-signal