随着Swift引入了类型安全的特性(泛型、类型推断),在RAC 3.0+后的使用与OC的RAC 2.5已经有了很大的不一样。 RAC 4 与 2.5信号的一个最大的区别就是强制区分出了热信号和冷信号。在2.5中不管冷热的信号都是RACSignal,在4.0+后热信号由Signal表示,冷信号由SignalProducer表示。具体的了解能够参照我以前翻译的一篇官方文档:《ReactiveCocoa 4 文档翻译:框架组成介绍》。swift
直接看下官方playground里的代码:安全
let (signal, observer) = Signal<Int, NoError>.pipe()
let subscriber1 = Observer<Int, NoError>(next: { print("Subscriber 1 received \($0)") } )
let subscriber2 = Observer<Int, NoError>(next: { print("Subscriber 2 received \($0)") } )
signal.observe(subscriber1)
//只有subscriber1收到了数据10
observer.sendNext(10)
// subscriber2也订阅了信号
signal.observe(subscriber2)
//subscriber1,subscriber2都收到了20
observer.sendNext(20)复制代码
假设这里是要建立一个热信号,那么用的是Signal下的静态方法:pipe()。 这个方法的泛型参数有两个:第一个表示信号里带的value的类型,第二个参数表示发生failed事件时,带的error的类型。返回值是是一个tuple,第一个值是建立的signal,第二个是用来手动控制发送事件的observer。闭包
接着建立了两个订阅者。订阅者Observer是一个结构体,两个泛型参数和Signal同样,表示next事件和failed事件中值的类型。 Observer能够订阅四种事件,初始化时能够传入对应的闭包对响应的事件作处理。这里直接贴出Observer的初始化源码:框架
public init(failed: (Error -> ())? = nil, completed: (() -> ())? = nil, interrupted: (() -> ())? = nil, next: (Value -> ())? = nil) {
self.init { event in
switch event {
case let .Next(value):
next?(value)
case let .Failed(error):
failed?(error)
case .Completed:
completed?()
case .Interrupted:
interrupted?()
}
}
}复制代码
由于四种事件都是可选的闭包,而且带了默认值,因此初始化时要注意本身须要处理几种事件,根据参数名传入对应的闭包。前面的demo中只处理next事件。函数
而后能够用pipe()返回的信号的对应的observer来发送事件。在前面示例中 observer.sendNext(10)
发送了一个next事件。也能够发送Failed、Completed、Interrupted事件。ui
SignalProducer的信号行为是冷信号,即每一个订阅者订阅的时候都会观察到相同的全部发出的事件。Signal是热信号,只会接收到订阅后发出的事件。 直接看下官方playground里的代码:spa
let producer = SignalProducer<Int, NoError> { observer, disposable in
observer.sendNext(1)
observer.sendNext(2)
}
let subscriber1 = Observer<Int, NoError>(next: { print("Subscriber 1 received \($0)") })
let subscriber2 = Observer<Int, NoError>(next: { print("Subscriber 2 received \($0)") })
producer.start(subscriber1)
// subscriber1,subscriber2都会收到发出的1,2的值
producer.start(subscriber2)复制代码
SignalProducer初始化的泛型参数和signal同样,可是只返回一个SignalProducer对象,observer作做为初始化闭包中的一个参数,和2.5中RACSignal初始化函数相似。 注意SignalProducer添加订阅者的方法与Signal不一样,使用的是start()方法。这样的语义也更明白一些。翻译
一个empty信号指立刻就发送completed事件,没有任何其余值。code
let emptySignal = Signal<Int, NoError>.empty
let emptyProducer = SignalProducer<Int, NoError>.empty复制代码
都是调用一个静态的合成属性empty。cdn
public static var empty: Signal {
return self.init { observer in
observer.sendCompleted()
return nil
}
}复制代码
其实实现也很简单,就是初始化后立刻发送一个完成的事件 empty的一个使用场景是做为一个高阶信号的value,有时一个产生信号的信号,里面这个信号的值可能并不重要,value就会放一个empty信号
never信号是一个不发送任何事件的信号。
let neverSignal = Signal<Int, NoError>.never
let neverProducer = SignalProducer<Int, NoError>.never复制代码
这个的实现也很简答,就是初始化之后什么都不作。
public static var never: SignalProducer {
return self.init { _ in return }
}复制代码
never一般也是使用在高阶函数的操做里,能够用来表示一个不会结束的信号。
欢迎关注个人微博:@没故事的卓同窗