2

The binding operator (<~) takes a BindingSource argument, both Signal and SignalProducer conform to the protocol

I would expect an UI element that is bound to a producer wouldn't "receive events" until the producer is started in some way but this does not seem to be the case

ie

let text = MutableProperty("abc")

myLabel1.reactive.text <~ text.signal
myLabel2.reactive.text <~ text.producer

text.value = "def"

causes both labels to update.

Is this intended behavior or am I misunderstanding something?

jjoelson
  • 5,771
  • 5
  • 31
  • 51
synndicate
  • 58
  • 8

2 Answers2

2

This is intended behavior. You can see in the implementation of <~ that start is called explicitly (and the producer's disposal is tied to the lifetime of the binding target).

[EDIT]

To clarify, it doesn't make much sense to bind the producer itself to a label in the way you are imagining. What would happen if start was called multiple times to produce multiple signals? Would the label get the values from the first signal, the most recent signal, or all signals merged together? There's no intuitive way for that to work.

jjoelson
  • 5,771
  • 5
  • 31
  • 51
  • It seems a SignalProducer shouldn't be a valid binding target for the reasons you provided? Having start being called implicitly (from the user's POV) goes against why Signals and Producers are differentiated in the first place no? – synndicate May 24 '17 at 23:00
  • I can see the confusion, but on the other hand `<~` is not the only function that implicitly starts a producer. `flatMap` is an extremely common operator that does the same. [This example](https://github.com/ReactiveCocoa/ReactiveSwift/blob/master/Documentation/Example.OnlineSearch.md#making-network-requests) from the Reactive-Swift docs uses `flatMap` to implicitly start producers even though none of the `start*` functions are anywhere to be seen. – jjoelson May 24 '17 at 23:16
2

The producer starts immediately when you call the binding operator <~.

The main difference between binding to a Signal and to a SignalProducer is that a SignalProducer can send values immediately when it starts.

Remove the last line of your example, you can see the difference:

myLabel1.text = ""
myLabel2.text = ""

let text = MutableProperty("abc")

myLabel1.reactive.text <~ text.signal // no change
myLabel2.reactive.text <~ text.producer // changed to "abc"

since text.producer sends its current value "abc" immediately when you start it, while text.signal only sends values of new updates.

So when you bind to a MutableProperty, in most cases you should bind to the producer of the property.

Cosyn
  • 4,404
  • 1
  • 33
  • 26