隨着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一般也是使用在高階函數的操做裏,能夠用來表示一個不會結束的信號。
歡迎關注個人微博:@沒故事的卓同窗