Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 427
cbowns Avatar asked Dec 20 '13 23:12

cbowns


1 Answers

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

like image 90
cbowns Avatar answered Sep 26 '22 07:09

cbowns