使用反应式cocoa简洁地获取本地数据,然后使用远程数据进行更新

时间:2014-03-05 04:19:17

标签: reactive-cocoa

我正在尝试实现一个可以执行的RACCommand,以启动向UI显示最新的可用数据。

sendNext:调用将分别从本地数据库和远程服务器返回数据。

是否有更简洁的方法来实现相同的行为?

self.testObjects = @[ @"initial" ];

RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    RACSignal *s1 = [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
        [subscriber sendNext:@[@"value1", @"value2"]];
        [subscriber sendCompleted];
        return [RACDisposable disposableWithBlock:^{
            // Cleanup
        }];
    }];

    RACSignal *s2 = [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
        [subscriber sendNext:@[ @"value1-updated", @"value2" ]];
        [subscriber sendCompleted];
        return [RACDisposable disposableWithBlock:^{
            // Cleanup
        }];
    }];

    return [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
        [s1 subscribeNext:^(id x) {
            [subscriber sendNext:x];
        }];

        [s1 subscribeCompleted:^{
            [s2 subscribeNext:^(id x) {
                [subscriber sendNext:x];
            }];
        }];

        return [RACDisposable disposableWithBlock:^{
            // Cleanup
        }];
    }];
}];

RACSignal *racSignal = [command.executionSignals switchToLatest];
RAC(self, testObjects) = racSignal;

[[self rac_valuesAndChangesForKeyPath:@"testObjects" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial observer:self] subscribeNext:^(RACTuple *x) {
    RACTupleUnpack(NSArray *values ) = x;
    NSLog(@"values: %@", values);
}];

[command execute:nil];

输出:

值:(     初始 )

值:(     值1,     值2 )

值:(     “VALUE1更新的”,     值2 )

1 个答案:

答案 0 :(得分:1)

假设您可以为s1s2中的每一个执行一次性清理操作(也就是说,假设您没有任何未提及的全局清理),可以使用-[RACSignal concat:]方法将这两个信号链接在一起:

RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    RACSignal *s1 = [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
        [subscriber sendNext:@[@"value1", @"value2"]];
        [subscriber sendCompleted];
        return [RACDisposable disposableWithBlock:^{
            // Cleanup
        }];
    }];

    RACSignal *s2 = [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
        [subscriber sendNext:@[ @"value1-updated", @"value2" ]];
        [subscriber sendCompleted];
        return [RACDisposable disposableWithBlock:^{
            // Cleanup
        }];
    }];

    return [s1 concat:s2];
}];

在这种情况下,-[RACSignal concat:]方法会创建一个信号,在s1上传递所有值,然后当s1完成时,会在s2上传递值,直到完成(此时返回的信号将完成)。