Reputation: 4254
Ok, I have a signal that sends an event when a certain method of a protocol gets called in response to some data getting retrieved from the server:
self.dataReceivedSignal = [[self rac_signalForSelector:@selector(didReceiveData:) fromProtocol:@protocol(DataServiceDelegate)] mapReplace:@YES];
This signal is then used to fire another signal that formats and returns the data:
- (RACSignal *)dataSignal
{
return [RACSignal combineLatest:@[self.dataReceivedSignal] reduce:^id(NSNumber * received){
...
return my_data;
}];
}
This view controller just listens to this second signal to get the data.
This works fine.
The problem is, the second time I enter this view controller, I don't want to load the data again, so I save it locally and do this:
if (!self.alreadyHasData) {
self.dataService = [[DataService alloc] init];
self.dataService.delegate = self;
[self.dataService getData];
} else {
self.dataReceivedSignal = [RACSignal return:@YES];
}
In case I already have the data, I'm replacing the dataReceivedSignal with a new one that just sends @YES and completes.
This works too, but that if/else doesn't seem too functional to me. Is this the correct approach?
Thanks.
Upvotes: 1
Views: 550
Reputation: 4485
First of all you can exchange combineLatest
to map
.
If you want not reload data if it's already loaded, you can write something like this:
- (RACSignal *)dataSignal
{
if (!_dataSignal) {
RACMulticastConnection *dataConnection = [[self.dataReceivedSignal map:^id(NSNumber * received){
/// ...
return my_data;
}] multicast:[RACReplaySubject replaySubjectWithCapacity:1]];
// Only do all of the above after one subscriber has attached.
_dataSignal = [RACSignal defer:^{
[dataConnection connect];
return dataConnection.signal;
}];
}
return _dataSignal;
}
And don't matter how much subscribers signal will have, retrieve data block will be called only one time.
Simpler code = better code. I think you can solve task with simpler solution without RAC.
Upvotes: 1