隨著Swift引入了類型安全的特性(泛型、類型推斷),在RAC 3.0+后的使用與OC的RAC 2.5已經(jīng)有了很大的不同。
RAC 4 與 2.5信號(hào)的一個(gè)最大的區(qū)別就是強(qiáng)制區(qū)分出了熱信號(hào)和冷信號(hào)。在2.5中無(wú)論冷熱的信號(hào)都是RACSignal,在4.0+后熱信號(hào)由Signal表示,冷信號(hào)由SignalProducer表示。具體的了解可以參照我之前翻譯的一篇官方文檔:《ReactiveCocoa 4 文檔翻譯:框架組成介紹》。
創(chuàng)建熱信號(hào):Signal
直接看下官方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收到了數(shù)據(jù)10
observer.sendNext(10)
// subscriber2也訂閱了信號(hào)
signal.observe(subscriber2)
//subscriber1,subscriber2都收到了20
observer.sendNext(20)
假設(shè)這里是要?jiǎng)?chuàng)建一個(gè)熱信號(hào),那么用的是Signal下的靜態(tài)方法:pipe()。
這個(gè)方法的泛型參數(shù)有兩個(gè):第一個(gè)表示信號(hào)里帶的value的類型,第二個(gè)參數(shù)表示發(fā)生failed事件時(shí),帶的error的類型。返回值是是一個(gè)tuple,第一個(gè)值是創(chuàng)建的signal,第二個(gè)是用來(lái)手動(dòng)控制發(fā)送事件的observer。
接著創(chuàng)建了兩個(gè)訂閱者。訂閱者Observer是一個(gè)結(jié)構(gòu)體,兩個(gè)泛型參數(shù)和Signal一樣,表示next事件和failed事件中值的類型。
Observer可以訂閱四種事件,初始化時(shí)可以傳入對(duì)應(yīng)的閉包對(duì)響應(yīng)的事件做處理。這里直接貼出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?()
}
}
}
因?yàn)樗姆N事件都是可選的閉包,并且?guī)Я四J(rèn)值,所以初始化時(shí)要注意自己需要處理幾種事件,根據(jù)參數(shù)名傳入對(duì)應(yīng)的閉包。前面的demo中只處理next事件。
然后可以用pipe()返回的信號(hào)的對(duì)應(yīng)的observer來(lái)發(fā)送事件。在前面示例中<code> observer.sendNext(10)</code>發(fā)送了一個(gè)next事件。也可以發(fā)送Failed、Completed、Interrupted事件。
創(chuàng)建冷信號(hào):SignalProducer
SignalProducer的信號(hào)行為是冷信號(hào),即每個(gè)訂閱者訂閱的時(shí)候都會(huì)觀察到相同的所有發(fā)出的事件。Signal是熱信號(hào),只會(huì)接收到訂閱后發(fā)出的事件。
直接看下官方playground里的代碼:
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都會(huì)收到發(fā)出的1,2的值
producer.start(subscriber2)
SignalProducer初始化的泛型參數(shù)和signal一樣,但是只返回一個(gè)SignalProducer對(duì)象,observer做作為初始化閉包中的一個(gè)參數(shù),和2.5中RACSignal初始化函數(shù)類似。
注意SignalProducer添加訂閱者的方法與Signal不同,使用的是start()方法。這樣的語(yǔ)義也更明白一些。
empty信號(hào)
一個(gè)empty信號(hào)指馬上就發(fā)送completed事件,沒(méi)有任何其他值。
let emptySignal = Signal<Int, NoError>.empty
let emptyProducer = SignalProducer<Int, NoError>.empty
都是調(diào)用一個(gè)靜態(tài)的合成屬性empty。
public static var empty: Signal {
return self.init { observer in
observer.sendCompleted()
return nil
}
}
其實(shí)實(shí)現(xiàn)也很簡(jiǎn)單,就是初始化后馬上發(fā)送一個(gè)完成的事件
empty的一個(gè)使用場(chǎng)景是作為一個(gè)高階信號(hào)的value,有時(shí)一個(gè)產(chǎn)生信號(hào)的信號(hào),里面這個(gè)信號(hào)的值可能并不重要,value就會(huì)放一個(gè)empty信號(hào)
never信號(hào)
never信號(hào)是一個(gè)不發(fā)送任何事件的信號(hào)。
let neverSignal = Signal<Int, NoError>.never
let neverProducer = SignalProducer<Int, NoError>.never
這個(gè)的實(shí)現(xiàn)也很簡(jiǎn)答,就是初始化以后什么都不做。
public static var never: SignalProducer {
return self.init { _ in return }
}
never通常也是使用在高階函數(shù)的操作里,可以用來(lái)表示一個(gè)不會(huì)結(jié)束的信號(hào)。
歡迎關(guān)注我的微博:@沒(méi)故事的卓同學(xué)
