特定信号发生前的缓冲信号

时间:2014-02-22 16:53:41

标签: objective-c reactive-cocoa

我想知道是否有可能累积在特定信号的next之间发生的信号结果。与

类似
[[[RACSignal
    combineLatest:@[signal1, signal2, signal3]]
    takeUntil:signal4]
    subscribeNext:^(id x) {
        // ...
    }];

但是在第一个signal4 next之后没有完成。

我正在使用的方案是我有一个显示viewController1的{​​{1}}。 viewController2允许用户更改影响viewController2中显示的数据的object。目前,我正在viewController1上展示objectChangedSignal并从viewController2收听。

但是,我希望直接从viewController1收到object的更改,但只有在它发出viewController1信号之后才会发出更改,并且只有在viewWillAppear之后发生了更改viewWillDisappear

希望它有意义,谢谢。

1 个答案:

答案 0 :(得分:2)

缓冲值的一种方法是使用-[RACSignal collect],它将它们收集到一个数组中,直到信号完成:

[[[RACSignal combineLatest:@[ s1, s2, s3 ]]
    collect]
    takeUntil:s4]

然而,您可能希望在最终信号上单独发送每个值,而不是值数组。您可以使用-[RACSignal flattenMap:]将这些值展平回最终信号:

[[[[RACSignal combineLatest:@[ s1, s2, s3 ]]
    collect]
    takeUntil:s4]
    flattenMap:^(NSArray *collected) {

        return [[collected rac_sequence] signal];

    }]

由于您不希望在s4之后完成信号,因此您可以在每次-repeat发送值后使用s4重新订阅。如果您没有这样做,-takeUntil:将导致您的信号在发生时完成。

[[[[[RACSignal combineLatest:@[ s1, s2, s3 ]]
    collect]
    takeUntil:s4]
    flattenMap:^(NSArray *collected) {

        return [[collected rac_sequence] signal];

    }]
    repeat]

请注意,如果任何组合信号是冷信号,重新订阅将导致其副作用发生更多次。因此,您可能必须通过组播它们(或组合信号)将它们转换为热信号:

RACMulticastConnection *mc = [[RACSignal combineLatest:@[ s1, s2, s3 ]] publish];
RACDisposable *d = [mc connect];
[[[mc.signal
    takeUntil:s4]
    flattenMap:^(NSArray *collected) {

        return [[collected rac_sequence] signal];

    }]
    repeat]

如果您的信号无限生存,您可能需要明确取消订阅(通过处置d)。

(Nota bene,此代码未经测试。)