Search code examples
reactive-cocoa

RACChannel: not seeing the two-way binding I expected


(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?


Solution

  • 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.)