7

(Open for comment from ReactiveCocoa guys on GitHub as well.)

I'm trying out ReactiveCocoa in a very simple RACTest (source is on GitHub) application in an attempt to firm up my theoretical understanding by actually using it.

I've got a RACChannel that, I thought, provided a two-way binding between a RAC()ed l-value and whatever I specified as arguments to RACChannel.

My usage looks like:

// Map the ticker's accumulationEnabled property to self.paused.
RAC(self, paused) = [RACChannelTo(_ticker, accumulateEnabled) deliverOn:[RACScheduler mainThreadScheduler]];

I'm seeing changes flow one direction, from _ticker.accumulateEnabled to self.paused, but changes to self.paused aren't flowing back to _ticker.

Have I misunderstood RACChannel? What's it for, and how is this not the expected usage?

cbowns
  • 6,295
  • 5
  • 47
  • 64

1 Answers1

10

I had misunderstood how to use RACChannel. Using RACChannelTo on both sides of the assignment works as expected:

RACChannelTo(self, paused) = RACChannelTo(_ticker, accumulateEnabled);

Main-thread delivery for changes to self.paused is a bit more complicated, but not terrible:

RACChannelTerminal *accumulateChannel = RACChannelTo(_ticker, accumulateEnabled);
RAC(self, paused) = [accumulateChannel deliverOn:RACScheduler.mainThreadScheduler];
[[RACObserve(self, paused) skip:1] subscribe:accumulateChannel];

(I'm still trying to understand why skip:1 is necessary, but without it, RAC blows out the stack, so I'm keeping it per the GitHub issue.)

cbowns
  • 6,295
  • 5
  • 47
  • 64
  • Did you find out what is the 'skip:1' ? – MCMatan Aug 26 '14 at 07:21
  • 1
    @PiratM yep, they answered it on Github (https://github.com/ReactiveCocoa/ReactiveCocoa/issues/1023#issuecomment-31053026): "The signals will send their initial values when you observe them. Since you only want to take the initial value from 1 side, you need to skip:1 to skip the initial value from the other side. Otherwise you'll be doing a=b; b=a." – cbowns Jan 27 '15 at 19:33
  • "So by placing my skip:1 in [[RACObserve(self, paused) skip:1] subscribe:accumulateChannel];, I'm saying, "sync all changes across to self.paused after the first one", correct?" "In that case, you're saying "ignore the initial value of self.paused, but any time it changes, update _ticker.accumulateEnabled."" – cbowns Jan 27 '15 at 19:34