ReactiveCocoa 3 和 ReactiveCocoa 4 中的多播

Multicasting in ReactiveCocoa 3 and ReactiveCocoa 4

假设我有一个 returns 一个 SignalProducer<AnyObject?, NSError> 的函数,我想将生产者绑定到多个 MutableProperty<String>。所以,像这样:

let foo = SignalProducer<AnyObject?, NSError>(value: nil)
let someProperty1 = MutableProperty<String>("")
let someProperty2 = MutableProperty<String>("")

someProperty1 <~ foo
    .flatMapError { _ in
        SignalProducer<AnyObject?, NoError>.empty
    }
    .map { _ in
        return "test"
    }

// someProperty2 <~ foo etc...

为了避免我的功能(例如一些网络内容)被 运行 多次,我需要使用多播。据我所知 CHANGELOGstartWithSignal 是用于此的运算符。但是我似乎无法弄清楚如何以声明的方式执行此操作。

因此,一种方法是在 startWithSignal:

的闭包中进行绑定
foo.startWithSignal { signal, disposable in
    someProperty1 <~ signal
        .map { _ in
            return "test"
        }

    // someProperty2 <~ signal etc...
}

然而这显然会失败,因为我们需要去掉 NSError 部分。因为我们给出了 Signal(与 SignalProducer 相对),所以我们不能使用 flatMapError(在 RAC4 中,catch 在 RAC3 中)。而且我不明白 mapError 如何为我们做到这一点?最后,我什至不确定这是在 RAC3/RAC4?

中处理多播的正确方法

非常感谢任何帮助。

starWithSignal

之前使用 flatMapError(以及任何其他必须采用 SignalProducer 参数的运算符)
let fooIgnoreError = foo
    .flatMapError { _ in
        SignalProducer<AnyObject?, NoError>.empty
    }


fooIgnoreError.startWithSignal { signal, disposable in
    someProperty1 <~ signal.map { _ in "test" }
    someProperty2 <~ signal.map { _ in "test2" }
}

如果 fooIgnoreError 只启动一次,您的底层信号生成器 foo 也保证只启动一次。

我用一个例子解释了如何实现多播

至于错误,你可以让你的属性AnyProperty<Result<Value, Error>>能够转发错误。如果你想让信号在失败时终止,你可以简单地

signal.flatMapError { error in 
    fatalError("Error: \(error)") // or some other form of error handling, or simply ignoring the error?
    return .empty
}