2015-08-25 2 views
6

Я использую ReactiveCocoa и у меня есть несколько SignalProducersReactiveCocoa объединить в одну SignalProducers

let center = NSNotificationCenter.defaultCenter() 
let signalProducer1 = center.rac_notification(name: notificationName1, object: nil) 
let signalProducer2 = center.rac_notification(name: notificationName2, object: nil) 
let signalProducer3 = center.rac_notification(name: notificationName3, object: nil) 

Я хочу, чтобы объединить их в единый сигнал производителя, который производит сигнал всякий раз, когда один из них производит сигнал.

Сначала функция combineLatest выглядела как хорошее решение

let combinedProducer = combineLatest(signalProducer1, signalProducer2, signalProducer3) 

Однако, согласно this article, в результате производитель только производит свой первый сигнал, когда все три дали сигнал.

This interactive diagram показывает именно то, что я хочу, поэтому я хочу использовать функцию flatten с помощью .Merge FlatteningStrategy. Однако мне сложно определить синтаксис, чтобы добиться этого.

+0

См. Https://github.com/ReactiveCocoa/ReactiveCocoa/blob/master/Documentation/BasicOperators.md#merging –

ответ

9

Вы можете добиться того, что следующим образом:

let merged = SignalProducer(values: [ signalProducer1, signalProducer2, signalProducer3 ]) 
    |> flatten(.Merge) 
+0

Как вы это сделаете в ReactiveCocoa 4? – mokagio

14

Update: RAC 4.2.1 и выше

Благодаря changes in how flatten works мы должны помочь компилятору быть более явной о типах:

let s1: SignalProducer<Int, NSError> = ... 
let s2: SignalProducer<Int, NSError> = ... 
let s3: SignalProducer<Int, NSError> = ... 


let _: SignalProducer<Int, NSError> = 
    SignalProducer<SignalProducer<Int, NSError>, NSError>(values: [s1, s2, s3]) 
     .flatten(.Merge) 

Это становится немного громоздким, поэтому вы можете разбить его:

let producers: SignalProducer<SignalProducer<Int, NSError>, NSError> = 
    SignalProducer(values: [s1, s2, s3]) 

let merged: SignalProducer<Int, NSError> = x.flatten(.Merge) 

Спасибо @Harry за комментарий, указывающий на выпуск новой версии.


RAC 4,2 и ниже

В RAC 4 это было бы

let merged = SignalProducer(values: [signalProducer1, signalProducer2, signalProducer3]) 
    .flatten(.Merge) 

На данный момент Xcode 7.1.1 не предполагает .flatten в окне автозавершения, что может привести к в вас (или просто мне) думая, что его нет, но если вы наберете все, то все будет работать.

+0

спасибо, очень полезно – asdf

+0

Это больше не работает с ReactiveCocoa 4.2.1 и выше кажется – Harry

+0

Спасибо @Harry за комментарий. Я обновляю ответ. – mokagio

Смежные вопросы