前面介紹了信號(hào),這里介紹一個(gè)信號(hào)發(fā)生器SignalProducer。關(guān)于信號(hào)發(fā)生器的圖例可參考自ReactiveCocoa 4 圖解之六——信號(hào)發(fā)生器(SignalProducer)。
冷信號(hào)
為什么稱(chēng)SignalProducer為冷信號(hào)抱虐,看下面例子:
let producer = SignalProducer<String, NoError>.init { (observer, _) in
print("新的訂閱,啟動(dòng)操作")
observer.send(value: "Hello")
observer.send(value: "World")
}
let subscriber1 = Observer<String, NoError>(value: { print("觀察者1接收到值 \($0)") })
let subscriber2 = Observer<String, NoError>(value: { print("觀察者2接收到值 \($0)") })
print("觀察者1訂閱信號(hào)發(fā)生器")
producer.start(subscriber1)
print("觀察者2訂閱信號(hào)發(fā)生器")
producer.start(subscriber2)
//注意:發(fā)生器將再次啟動(dòng)工作
打印結(jié)果:
觀察者1訂閱信號(hào)發(fā)生器 新的訂閱,啟動(dòng)操作 觀察者1接收到值 Hello 觀察者1接收到值 World 觀察者2訂閱信號(hào)發(fā)生器 新的訂閱逞刷,啟動(dòng)操作 觀察者2接收到值 Hello 觀察者2接收到值 World
所以稱(chēng)SignalProducer是冷信號(hào)嘉涌,任何一個(gè)訂閱者/觀察者都不會(huì)錯(cuò)過(guò)任何事件。start方法有關(guān)聯(lián)一個(gè)觀察者并激活信號(hào)的功能夸浅。
SignalProducer.empty
let emptyProducer = SignalProducer<String, NoError>.empty
let observer = Observer<String, NoError>.init(value:{ _ in print("打印值") },
failed: { _ in print("失敗調(diào)用") },
completed: { _ in print("完成調(diào)用") },
interrupted:{ _ in print("阻斷調(diào)用") })
emptyProducer.start(observer)
打印結(jié)果:
完成調(diào)用
注意:這里打印的是“完成調(diào)用”仑最, 而Signal調(diào)用的是interrupted》可能是為了區(qū)分Signal是有時(shí)序的警医,SignalProducer是沒(méi)有時(shí)序的。
SignalProducer.never
會(huì)返回一個(gè)什么都不會(huì)發(fā)送信號(hào)的生成器坯钦,同上预皇。
buffer
創(chuàng)建一個(gè)時(shí)間隊(duì)列可以回放已經(jīng)發(fā)送的事件 在5.0已移除API
startWithXXX
如startWithSignal, 返回信號(hào)開(kāi)始發(fā)送的事件
print("-------------------startWithSignal-------------------")
var v1: String?
SignalProducer<String, NoError>.init(value: "Hello")
.on(value: { (text) in
v1 = text
})
.startWithSignal { (signal, disposable) in
print(signal)
print(v1) //nil
}
print(v1)
print("-------------------startWithValues-------------------")
SignalProducer<String, NoError>.init(value: "Hello")
.startWithValues { (value) in
print(value)
}
打印結(jié)果:
-------------------startWithSignal------------------- ReactiveSwift.Signal<Swift.String, Result.NoError> nil Optional("Hello") -------------------startWithValues------------------- Hello
總結(jié)起來(lái):startWithCompleted婉刀、startWithFailed吟温、startWithInterrupted同startWithValues,只不過(guò)只能接受相應(yīng)的事件
lift
var word = ""
let transform: (Signal<String, NoError>) -> Signal<String, NoError> = { signal in
word = "Hello"
return signal
}
SignalProducer<String, NoError>.init(value: "").lift(transform).startWithValues { (_) in
print(word)
}
會(huì)打油患铡:Hello
這個(gè)個(gè)人覺(jué)得較難理解鲁豪,“提起”對(duì)信號(hào)發(fā)生器進(jìn)行操作,可理解為所有的原函數(shù)都是通過(guò)lift去實(shí)現(xiàn)的律秃,接用中間信號(hào)來(lái)實(shí)現(xiàn)一系列的信號(hào)變換爬橡。
map
匹配值轉(zhuǎn)換為新的值
mapError
把收到的error轉(zhuǎn)換為新的Error
filter
過(guò)濾不符合條件的值
take
去前幾次的值
以上都和熱信號(hào)相關(guān)API使用類(lèi)似。
observeOn
最后在介紹一個(gè)observeOn, 即在指定的調(diào)度器上分發(fā)事件
let baseProducer = SignalProducer<String, NoError>.init(values: ["Hello", "Nice", "to", "meet", "you"])
let completion = {
print("是主線程嗎友绝?\(Thread.current.isMainThread)")
}
//主線程
baseProducer.observe(on: QueueScheduler(qos: DispatchQoS.default, name: "test")).startWithCompleted(completion)
//非主線程
baseProducer.startWithCompleted(completion)
打印結(jié)果:
是主線程嗎堤尾?true 是主線程嗎?false
相關(guān)鏈接:
Swift 響應(yīng)式編程FRP使用RAC學(xué)習(xí)筆記1
Swift 響應(yīng)式編程FRP使用RAC學(xué)習(xí)筆記2