ReactiveCocoa:手动发送事件

时间:2014-10-02 08:47:58

标签: objective-c reactive-cocoa

好的,我有一个信号,当一个协议的某个方法被调用以响应从服务器检索到的某些数据时发送一个事件:

self.dataReceivedSignal = [[self rac_signalForSelector:@selector(didReceiveData:) fromProtocol:@protocol(DataServiceDelegate)] mapReplace:@YES];

然后,此信号用于触发另一个格式化并返回数据的信号:

- (RACSignal *)dataSignal
{
    return [RACSignal combineLatest:@[self.dataReceivedSignal] reduce:^id(NSNumber * received){
        ...
        return my_data;
    }];
}

此视图控制器只是侦听第二个信号以获取数据。

这很好用。

问题是,第二次进入这个视图控制器时,我不想再次加载数据,所以我在本地保存它并执行此操作:

if (!self.alreadyHasData) {
    self.dataService = [[DataService  alloc] init];
    self.dataService.delegate = self;
    [self.dataService getData];
} else {
    self.dataReceivedSignal = [RACSignal return:@YES];
}

如果我已经拥有数据,我将使用刚发送@YES并完成的新数据替换dataReceivedSignal。

这也有效,但是if / else对我来说似乎不太合适。这是正确的方法吗?

感谢。

1 个答案:

答案 0 :(得分:1)

首先,您可以将combineLatest兑换为map。 如果您不想重新加载已加载的数据,可以这样写:

- (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;
}

无论用户信号有多少,检索数据块只会被调用一次。

更简单的代码=更好的代码。我认为你可以在没有RAC的情况下通过更简单的解决方案来解决任务。