ObjectiveCBridging
RACSignal -> Signal,SignalProducer
RACCommand -> Action
RACScheduler -> SchedulerType
RACDisposable -> Disposable
具体可以参看ObjectiveCBridging.swift
RAC4的 Signal 对应RAC2的 RACSubject,为热信号,SignalProducer 对应 RACSignal 为冷信号。
形象的说:热信号像是直播,冷信号像是点播
热信号
参看一个例子
// 创建信号 let (signal,observer) = Signal<String,NSError>.pipe() // 监听器1:立即监听 signal.observeResult { NSLog("Subscriber 1 get a next value: \($0)") } // 监听器2:0.1s后监听 QueueScheduler.mainQueueScheduler.scheduleAfter(NSDate(timeIntervalSinceNow: 0.1)) { signal.observeResult({ (result) in NSLog("Subscriber 2 get a next value: \(result)") }) } // 发送Next信号:1s后发送"package 1" QueueScheduler.mainQueueScheduler.scheduleAfter(NSDate(timeIntervalSinceNow: 1)) { NSLog("Signal send package 1 ...") observer.sendNext("package 1") } // 监听器3:1.1s后监听 QueueScheduler.mainQueueScheduler.scheduleAfter(NSDate(timeIntervalSinceNow: 1.1)) { signal.observeResult { NSLog("Subscriber 3 get a next value: \($0)") } } // 发送Next信号: 2s后发送"package 2" QueueScheduler.mainQueueScheduler.scheduleAfter(NSDate(timeIntervalSinceNow: 2)) { NSLog("signal send package 2 ...") observer.sendNext("package 2") }
运行:
2016-12-18 19:42:16.206588 TestRAC4[695:389286] start ... 2016-12-18 19:42:17.249072 TestRAC4[695:389286] Signal send package 1 ... 2016-12-18 19:42:17.254583 TestRAC4[695:389286] Subscriber 1 get a next value: .Success(package 1) 2016-12-18 19:42:17.254899 TestRAC4[695:389286] Subscriber 2 get a next value: .Success(package 1) 2016-12-18 19:42:18.393983 TestRAC4[695:389286] signal send package 2 ... 2016-12-18 19:42:18.394386 TestRAC4[695:389286] Subscriber 1 get a next value: .Success(package 2) 2016-12-18 19:42:18.394582 TestRAC4[695:389286] Subscriber 2 get a next value: .Success(package 2) 2016-12-18 19:42:18.394769 TestRAC4[695:389286] Subscriber 3 get a next value: .Success(package 2)
正如之前提到的热信号的特点,热信号不关心是否有人监听,有产生信号就发送,有人监听就发个监听者。0.1s,2s分别发送next事件,0s,0.1s,1.1s分别产生一个监听者,所以第一个信号只有监听者1,2能收到;第二个next发出时三个监听器都准备好了,都能收到。
冷信号
再看看冷信号的例子:
let producer = SignalProducer<String,NSError>.init { (observer,_) in QueueScheduler.mainQueueScheduler.scheduleAfter(NSDate(timeIntervalSinceNow: 1)) { NSLog("Producer send package 1 ...") observer.sendNext("package 1") } QueueScheduler.mainQueueScheduler.scheduleAfter(NSDate(timeIntervalSinceNow: 2)) { NSLog("Producer send package 2 ...") observer.sendNext("package 2") } } QueueScheduler.mainQueueScheduler.scheduleAfter(NSDate(timeIntervalSinceNow: 2)) { NSLog("setup Subsrciber 1") producer.startWithResult({ (msg) in NSLog("Subscriber 1 get a next value: \(msg)") }) } QueueScheduler.mainQueueScheduler.scheduleAfter(NSDate(timeIntervalSinceNow: 3)) { NSLog("setup Subsrciber 2") producer.startWithResult({ (msg) in NSLog("Subscriber 2 get a next value: \(msg)") }) }
以下是输出:
2016-12-18 20:05:36.396118 TestRAC4[703:394073] start ... 2016-12-18 20:05:38.600637 TestRAC4[703:394073] setup Subsrciber 1 2016-12-18 20:05:39.681697 TestRAC4[703:394073] setup Subsrciber 2 2016-12-18 20:05:39.682077 TestRAC4[703:394073] Producer send package 1 ... 2016-12-18 20:05:39.685559 TestRAC4[703:394073] Subscriber 1 get a next value: .Success(package 1) 2016-12-18 20:05:40.753463 TestRAC4[703:394073] Producer send package 2 ... 2016-12-18 20:05:40.753865 TestRAC4[703:394073] Subscriber 1 get a next value: .Success(package 2) 2016-12-18 20:05:40.754679 TestRAC4[703:394073] Producer send package 1 ... 2016-12-18 20:05:40.754898 TestRAC4[703:394073] Subscriber 2 get a next value: .Success(package 1) 2016-12-18 20:05:41.881230 TestRAC4[703:394073] Producer send package 2 ... 2016-12-18 20:05:41.881673 TestRAC4[703:394073] Subscriber 2 get a next value: .Success(package 2)
使用冷信号,信号在程序起来第1s,2s分别发送了一个next。而在2s,3s分别建立了一个监听。第一个监听建立后1s,2s分别收到一个信号。第二信号建立的1s,2s后也分别收到了同样的信号。
冷信号转化为特殊热信号
由于冷信号每次订阅都重新发送事件,故有时候我们需要多次订阅时会造成不希望的重复发送(这称为信号的副作用),我们需要将冷信号转为具有热信号特征的冷信号。
参看一个例子,我们用冷,热信号在0.1s后发送三个next事件,然后如下进行监听:
// 我们用2个监控来监控generateSignal()产生的信号 let signal = generateSignal() signal.startWithResult{ NSLog("Subscriber 1 get a next value: \($0)") } QueueScheduler.mainQueueScheduler.scheduleAfter(NSDate(timeIntervalSinceNow: 1)) { signal.startWithResult{ NSLog("Subscriber 2 get a next value: \($0)") } }
先看看如果是产生了普通的冷信号:
func generateSignal() -> SignalProducer<String,NSError> { let producer = SignalProducer<String,_) in QueueScheduler.mainQueueScheduler.scheduleAfter(NSDate(timeIntervalSinceNow: 1)) { NSLog("producer send package 1 ...") observer.sendNext("package 1") NSLog("producer send package 2 ...") observer.sendNext("package 2") NSLog("producer send package 3 ...") observer.sendNext("package 3") } } return producer }
输出如我们所料,信号被重复发送了。
2016-12-18 21:46:21.295670 TestRAC4[742:413995] start ... 2016-12-18 21:46:22.389634 TestRAC4[742:413995] producer send package 1 ... 2016-12-18 21:46:22.397032 TestRAC4[742:413995] Subscriber 1 get a next value: .Success(package 1) 2016-12-18 21:46:22.397397 TestRAC4[742:413995] producer send package 2 ... 2016-12-18 21:46:22.398235 TestRAC4[742:413995] Subscriber 1 get a next value: .Success(package 2) 2016-12-18 21:46:22.398415 TestRAC4[742:413995] producer send package 3 ... 2016-12-18 21:46:22.398608 TestRAC4[742:413995] Subscriber 1 get a next value: .Success(package 3) 2016-12-18 21:46:23.496484 TestRAC4[742:413995] producer send package 1 ... 2016-12-18 21:46:23.496886 TestRAC4[742:413995] Subscriber 2 get a next value: .Success(package 1) 2016-12-18 21:46:23.497061 TestRAC4[742:413995] producer send package 2 ... 2016-12-18 21:46:23.497255 TestRAC4[742:413995] Subscriber 2 get a next value: .Success(package 2) 2016-12-18 21:46:23.497413 TestRAC4[742:413995] producer send package 3 ... 2016-12-18 21:46:23.498869 TestRAC4[742:413995] Subscriber 2 get a next value: .Success(package 3)
如果改成热信号呢?
func generateSignal() -> Signal<String,NSError> { let (signal,NSError>.pipe() QueueScheduler.mainQueueScheduler.scheduleAfter(NSDate(timeIntervalSinceNow: 0.1)) { NSLog("producer send package 1 ...") observer.sendNext("package 1") NSLog("producer send package 2 ...") observer.sendNext("package 2") NSLog("producer send package 3 ...") observer.sendNext("package 3") } return signal } let signal = generateSignal() signal.observeResult { NSLog("Subscriber 1 get a next value: \($0)") } QueueScheduler.mainQueueScheduler.scheduleAfter(NSDate(timeIntervalSinceNow: 1)) { signal.observeResult{ NSLog("Subscriber 2 get a next value: \($0)") } }
输出也如我们所料,只有监听2能搜到事件,且信号都只发送一次。
2016-12-18 21:54:34.527911 TestRAC4[745:415500] start ... 2016-12-18 21:54:34.634711 TestRAC4[745:415500] producer send package 1 ... 2016-12-18 21:54:34.637899 TestRAC4[745:415500] Subscriber 1 get a next value: .Success(package 1) 2016-12-18 21:54:34.638067 TestRAC4[745:415500] producer send package 2 ... 2016-12-18 21:54:34.638146 TestRAC4[745:415500] Subscriber 1 get a next value: .Success(package 2) 2016-12-18 21:54:34.638195 TestRAC4[745:415500] producer send package 3 ... 2016-12-18 21:54:34.638334 TestRAC4[745:415500] Subscriber 1 get a next value: .Success(package 3)
缓冲 buffer
通过SignalProducer.buffer()创建,是一个事件的队列(通常指定数量),当新信号产生时,会重新执行队列里的事件。和pipe相似,这个方法返回一个观察者。每个发给这个观察者的事件会被加入队列。如果这个缓冲区已经达到创建时预定的数量,当新的事件发来时,最早的一个会被移出队列。
如果使用buffer来处理呢?我们将上面的冷信号稍作修改:
func generateSignal() -> SignalProducer<String,NSError> { let (producer,observer) = SignalProducer<String,NSError>.buffer(Int.max) QueueScheduler.mainQueueScheduler.scheduleAfter(NSDate(timeIntervalSinceNow: 1)) { NSLog("producer send package 1 ...") observer.sendNext("package 1") NSLog("producer send package 2 ...") observer.sendNext("package 2") NSLog("producer send package 3 ...") observer.sendNext("package 3") } return producer }
输出发现,似乎冷信号变成了热信号了,只发送了一次。但又具有冷信号的特点:两个监听器都能收到事件。
2016-12-18 21:44:29.971493 TestRAC4[740:413482] start ... 2016-12-18 21:44:31.071352 TestRAC4[740:413482] producer send package 1 ... 2016-12-18 21:44:31.075839 TestRAC4[740:413482] Subscriber 1 get a next value: .Success(package 1) 2016-12-18 21:44:31.076115 TestRAC4[740:413482] producer send package 2 ... 2016-12-18 21:44:31.076580 TestRAC4[740:413482] Subscriber 1 get a next value: .Success(package 2) 2016-12-18 21:44:31.076773 TestRAC4[740:413482] producer send package 3 ... 2016-12-18 21:44:31.077035 TestRAC4[740:413482] Subscriber 1 get a next value: .Success(package 3) 2016-12-18 21:44:31.078167 TestRAC4[740:413482] Subscriber 2 get a next value: .Success(package 1) 2016-12-18 21:44:31.078420 TestRAC4[740:413482] Subscriber 2 get a next value: .Success(package 2) 2016-12-18 21:44:31.078771 TestRAC4[740:413482] Subscriber 2 get a next value: .Success(package 3)
buffer(Int.max)这里的参数表示这个缓冲大小,如果设置为1,那么第二个next发出时,缓存里第一个就被替换成了第二个next,第三个来时同理。对于第一个监听者它能收到全部事件;对于第二个监听者只能收到缓存里的事件也就是最后的package 3。如果这第一个监听者在发出信号之后再开始监听,那么它也将和第二个监听者一样只能收到缓冲里的事件。
replayLazily
假如我们不能修generateSignal()里的代码,这是由第三方提供的,我们可以使用replayLazily。
let producer = generateSignal().replayLazily(Int.max) // 直接用之前的冷信号 producer.startWithResult { NSLog("Subscriber 1 get a next value: \($0)") } QueueScheduler.mainQueueScheduler.scheduleAfter(NSDate(timeIntervalSinceNow: 1)) { producer.startWithResult { NSLog("subscriber 2 get a next value: \($0)") } }
2016-12-18 22:04:48.364076 TestRAC4[753:417953] start ... 2016-12-18 22:04:48.482124 TestRAC4[753:417953] producer send package 1 ... 2016-12-18 22:04:48.484271 TestRAC4[753:417953] Subscriber 1 get a next value: .Success(package 1) 2016-12-18 22:04:48.484422 TestRAC4[753:417953] producer send package 2 ... 2016-12-18 22:04:48.484665 TestRAC4[753:417953] Subscriber 1 get a next value: .Success(package 2) 2016-12-18 22:04:48.484852 TestRAC4[753:417953] producer send package 3 ... 2016-12-18 22:04:48.485120 TestRAC4[753:417953] Subscriber 1 get a next value: .Success(package 3) 2016-12-18 22:04:49.454274 TestRAC4[753:417953] subscriber 2 get a next value: .Success(package 1) 2016-12-18 22:04:49.454659 TestRAC4[753:417953] subscriber 2 get a next value: .Success(package 2) 2016-12-18 22:04:49.454897 TestRAC4[753:417953] subscriber 2 get a next value: .Success(package 3)
那么replayLazily(Int.max)这个参数和buffer的相同吗?我们修改成1或2一看就知道。答案是相同
原文链接:https://www.f2er.com/react/305229.html