2014-02-22 50 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