2014-02-22 17 views
0

我想知道是否有可能累积特定信号的next之间发生的信号结果。类似特定信号出现之前的缓冲信号

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

但第signal4next后没有完成。

我正在使用的场景是我有一个viewController1,其中显示viewController2viewController2允许用户更改影响viewController1中显示的数据的object。目前我在viewController2上曝光objectChangedSignal并从viewController1收听。

不过,我希望收到直接从viewController1但只有它激发viewWillAppear信号且仅当viewController1viewWillDisappear后发生变化后object的变化。

希望它是有道理的,谢谢。

回答

2

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

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

Howevever,你可能希望每个值将在最后的信号,而不是单独发送值的数组。您可以使用-[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)如果你的信号,否则会住无限。

(注意,此代码未经测试。)

+0

谢谢您的广泛答案!但它并没有真正以我想象的方式工作。很可能是由于任务描述不佳:'s1','s2'和's3'不一定会触发。但如果他们这样做,我只希望在's4'发射后才能得到通知。 –

+0

如果's1','s2'或s3'中的任何一个没有发送一个值,那么'-combineLatest:'不会发送一个值 - 它会一直等待,直到发送给它的每个信号都在发送之前发送一个值值的元组。 (有些方法可以处理这个问题,比如使用'-startWith:'。) 它听起来像' - [takeUntil:s4]'不是你想要的,因为这个*完成* s4'时的信号火灾。也许你想要一个'-skipUntilBlock:','-skipWhileBlock:',或'-if:then:else:'operations? – erikprice