ReactiveCocoa4中的冷信號(hào)和熱信號(hào)

在閱讀本文之前研乒,強(qiáng)烈安利以下三篇文章:
細(xì)說(shuō)ReactiveCocoa的冷信號(hào)與熱信號(hào)(一)
細(xì)說(shuō)ReactiveCocoa的冷信號(hào)與熱信號(hào)(二):為什么要區(qū)分冷熱信號(hào)
細(xì)說(shuō)ReactiveCocoa的冷信號(hào)與熱信號(hào)(三):怎么處理冷信號(hào)與熱信號(hào)

在RAC4中徘郭,Singal對(duì)應(yīng)RAC2中的RACSubject即為熱信號(hào),而SignalProducer對(duì)應(yīng)RAC2中的RACSignal即為了冷信號(hào)。冷信號(hào)和熱信號(hào)的區(qū)別,可參考以上三篇文章。

1. 熱信號(hào)Signal

為了驗(yàn)證Signal具有熱信號(hào)的特點(diǎn)坝初,進(jìn)行如下實(shí)驗(yàn)

let (signal, observer) = Signal<String, NSError>.pipe()

//訂閱者1
QueueScheduler.mainQueueScheduler.scheduleAfter(0.1) {
  signal.observeNext {
      NSLog("Subscriber 1 get a next value: \($0) from signal")
  }
}

//訂閱者2
signal.observeNext {
  NSLog("Subscriber 2 get a next value: \($0) from signal")
}

//開(kāi)始發(fā)送第一個(gè)包
QueueScheduler.mainQueueScheduler.scheduleAfter(1) {
  NSLog("signal send package 1"); observer.sendNext("send package 1")
}

//訂閱者3
QueueScheduler.mainQueueScheduler.scheduleAfter(1.1) {
  signal.observeNext {
      NSLog("Subscriber 3 get a next value: \($0) from signal")
  }
}

//發(fā)送第二個(gè)包
QueueScheduler.mainQueueScheduler.scheduleAfter(2) {
  NSLog("signal send package 2"); observer.sendNext("send package 2")
}

按照時(shí)間順序來(lái)解釋上述代碼:

  1. 0s 創(chuàng)建signal這個(gè)熱信號(hào)
  2. 立即訂閱該信號(hào)浸剩,該訂閱者命名為訂閱者2
  3. 0.1s訂閱剛剛創(chuàng)建的熱信號(hào)Signal钾军,該訂閱者命名為訂閱者1
  4. 1ssignal發(fā)送第一個(gè)包
  5. 1.1s后訂閱該信號(hào)鳄袍,該訂閱者命名為訂閱者3
  6. 2s后signal發(fā)送第二個(gè)包

看一下程序的運(yùn)行情況

2016-04-19 17:37:30.242 ColdSignalAndHotSignal[29298:3700008] Start
2016-04-19 17:37:30.245 ColdSignalAndHotSignal[29298:3700008] Subscriber 2 subscribe
2016-04-19 17:37:30.366 ColdSignalAndHotSignal[29298:3700008] Subscriber 1 subscribe
2016-04-19 17:37:31.295 ColdSignalAndHotSignal[29298:3700008] signal send package 1
2016-04-19 17:37:31.298 ColdSignalAndHotSignal[29298:3700008] Subscriber 2 get a next value: send package 1 from signal
2016-04-19 17:37:31.299 ColdSignalAndHotSignal[29298:3700008] Subscriber 1 get a next value: send package 1 from signal
2016-04-19 17:37:31.434 ColdSignalAndHotSignal[29298:3700008] Subscriber 3 subscribe
2016-04-19 17:37:32.246 ColdSignalAndHotSignal[29298:3700008] signal send package 2
2016-04-19 17:37:32.246 ColdSignalAndHotSignal[29298:3700008] Subscriber 2 get a next value: send package 2 from signal
2016-04-19 17:37:32.246 ColdSignalAndHotSignal[29298:3700008] Subscriber 1 get a next value: send package 2 from signal
2016-04-19 17:37:32.246 ColdSignalAndHotSignal[29298:3700008] Subscriber 3 get a next value: send package 2 from signal

分析輸出結(jié)果:

  1. 30.242s, signal創(chuàng)建,開(kāi)始計(jì)時(shí)
  2. 30.245s吏恭,即0s后拗小,訂閱者2訂閱signal
  3. 30.366s,即0.1s后,訂閱者1訂閱signal樱哼,可以看到訂閱者1哀九、2的訂閱時(shí)間相差約0.1s
  4. 31.295s,即1s后搅幅,signal發(fā)送第一個(gè)包
  5. 31.298s阅束,即1s后,訂閱者2接收到signal發(fā)送的包,并打印出來(lái)茄唐∠⒙悖可以看到signal一發(fā)送,訂閱者立刻就接受到
  6. 31.299s沪编,即1s后呼盆,訂閱者1接收到signal發(fā)送的包,并打印出來(lái)蚁廓。幾乎和訂閱者2同時(shí)接收到包
  7. 31.434s访圃,即1.1s后,訂閱者3訂閱signal相嵌,注意訂閱者3并沒(méi)有收到第一個(gè)包
  8. 32.246s腿时,即2s后,signal發(fā)送第二個(gè)包
  9. 32.246s饭宾,即2s后批糟,訂閱者2立即接收到signal發(fā)送的包
  10. 32.246s,即2s后捏雌,訂閱者1立即接收到signal發(fā)送的包
  11. 32.246s跃赚,即2s后,訂閱者3立即接收到signal發(fā)送的包

根據(jù)上面的分析結(jié)果可知:

  1. 訂閱者對(duì)熱信號(hào)沒(méi)有任何影響性湿,無(wú)論是否有訂閱者訂閱熱信號(hào)纬傲,熱信號(hào)都會(huì)發(fā)送事件
  2. 訂閱者幾乎是同時(shí)接收到信號(hào)發(fā)出的事件(忽略微小的延遲)
  3. 如果訂閱者在熱信號(hào)發(fā)送事件之后在訂閱,訂閱者無(wú)法接收到訂閱之前的事件

因此肤频,根據(jù)熱信號(hào)的特點(diǎn)叹括,可以得到下圖:


熱信號(hào).png

2. 冷信號(hào)SignalProducer

同樣為了驗(yàn)證SignalProducer具有冷信號(hào)的特點(diǎn),進(jìn)行如下實(shí)驗(yàn)

NSLog("producer start")
let producer = SignalProducer<String, NSError> {
    sink, _ in
    //開(kāi)始發(fā)送第一個(gè)包
    QueueScheduler.mainQueueScheduler.scheduleAfter(1) {
        NSLog("producer send package 1"); sink.sendNext("send package 1")
    }
    //發(fā)送第二個(gè)包
    QueueScheduler.mainQueueScheduler.scheduleAfter(2) {
        NSLog("producer send package 2"); sink.sendNext("send package 2")
    }
}

//訂閱者1
QueueScheduler.mainQueueScheduler.scheduleAfter(2) {
    NSLog("Subscriber 1")
    producer.startWithNext {
        NSLog("Subscriber 2 get a next value: \($0) from producer")
    }
}

//訂閱者2
QueueScheduler.mainQueueScheduler.scheduleAfter(3) {
    NSLog("Subscriber 2")
    producer.startWithNext {
        NSLog("Subscriber 2 get a next value: \($0) from producer")
    }
}

按照時(shí)間順序來(lái)解釋上述代碼:

  1. 0s創(chuàng)建冷信號(hào)producer
  2. 1sproducer發(fā)送第一個(gè)包
  3. 2sproducer發(fā)送第二個(gè)包
  4. 2s宵荒,訂閱冷信號(hào)producer該訂閱者命名為訂閱者1
  5. 3s汁雷,訂閱冷信號(hào)producer該訂閱者命名為訂閱者2
2016-04-20 10:43:45.683 ColdSignalAndHotSignal[32370:4197730] producer start
2016-04-20 10:43:47.886 ColdSignalAndHotSignal[32370:4197730] Subscriber 1
2016-04-20 10:43:48.685 ColdSignalAndHotSignal[32370:4197730] Subscriber 2
2016-04-20 10:43:48.889 ColdSignalAndHotSignal[32370:4197730] producer send package 1
2016-04-20 10:43:48.892 ColdSignalAndHotSignal[32370:4197730] Subscriber 1 get a next value: send package 1 from producer
2016-04-20 10:43:49.685 ColdSignalAndHotSignal[32370:4197730] producer send package 1
2016-04-20 10:43:49.686 ColdSignalAndHotSignal[32370:4197730] Subscriber 2 get a next value: send package 1 from producer
2016-04-20 10:43:49.890 ColdSignalAndHotSignal[32370:4197730] producer send package 2
2016-04-20 10:43:49.890 ColdSignalAndHotSignal[32370:4197730] Subscriber 1 get a next value: send package 2 from producer
2016-04-20 10:43:50.686 ColdSignalAndHotSignal[32370:4197730] producer send package 2
2016-04-20 10:43:50.686 ColdSignalAndHotSignal[32370:4197730] Subscriber 2 get a next value: send package 2 from producer

分析輸出結(jié)果

  1. 45.683s净嘀,創(chuàng)建冷信號(hào)
  2. 47.886s,即2s后侠讯,訂閱者1訂閱冷信號(hào)producer
  3. 48.685s挖藏,即3s后,訂閱者2訂閱冷信號(hào)producer
  4. 48.889s厢漩,即3s后膜眠,producer發(fā)送第一個(gè)包,(為什么是在3s后發(fā)送溜嗜?)
  5. 48.892s宵膨,即3s后,與此同時(shí)炸宵,訂閱者1接收到producer發(fā)出的第一個(gè)包
  6. 49.685s辟躏,即4s后,producer再次發(fā)送第一個(gè)包(為什么又發(fā)送一次土全?)
  7. 49.686s捎琐,即4s后,與此同時(shí)涯曲,訂閱者2接收到producer發(fā)送的第一個(gè)包
  8. 49.890s野哭,即4s后,producer發(fā)送第二個(gè)包
  9. 49.890s幻件,即4s后拨黔,與此同時(shí),訂閱者1接收到producer發(fā)出的第二個(gè)包
  10. 50.686s绰沥,即5s后篱蝇,producer再次發(fā)送第二個(gè)包
  11. 50.686s,即5s后徽曲,與此同時(shí)零截,訂閱者2接收到producer發(fā)出的第二個(gè)包

雖然輸出結(jié)果混合在一起,但通過(guò)分析可以得知4秃臣、6提出的問(wèn)題

為什么producer是在3s后發(fā)送第一個(gè)包涧衙?

因?yàn)椋嗛喺?是在2s后才訂閱冷信號(hào)producer奥此,然后producer在1s后發(fā)給訂閱者1第一個(gè)包(注意:是發(fā)給訂閱者1)弧哎,這也解釋了為什么producer每個(gè)包會(huì)發(fā)兩遍

為什么又發(fā)送一次?

producer再次發(fā)送第一個(gè)包是發(fā)送給訂閱者2的稚虎,而訂閱者2是在3s后才訂閱冷信號(hào)producer撤嫩,然后producer在1s后發(fā)給訂閱者2第一個(gè)包

上面分析也證明了SignalProducer具有冷信號(hào)的特點(diǎn)

  1. SignalProducer`是一對(duì)一發(fā)送,這句話可能不好理解蠢终。這里可以理解成序攘,有幾個(gè)訂閱者茴她,冷信號(hào)就發(fā)送幾次同樣的信號(hào)
  2. 每個(gè)訂閱者都能接收到同樣的事件。例如上面訂閱者2在3s后訂閱程奠,那它就在4s后和5s后接收到事件

因此丈牢,根據(jù)冷信號(hào)的特點(diǎn),可以得到下圖:


冷信號(hào).png

細(xì)說(shuō)ReactiveCocoa的冷信號(hào)與熱信號(hào)(三):怎么處理冷信號(hào)與熱信號(hào)有一句話很形象地說(shuō)明了冷熱信號(hào)的特點(diǎn):

熱信號(hào)類似“直播”梦染,錯(cuò)過(guò)了就不再處理赡麦。而冷信號(hào)類似“點(diǎn)播”朴皆,每次訂閱都會(huì)從頭開(kāi)始帕识。

由上述分析,可以得知RAC2和RAC4中的冷熱信號(hào)有如下關(guān)系:

RAC2 RAC4
冷信號(hào) RACSignal SignalProducer
熱信號(hào) RACSubject Singal

3. 冷信號(hào)的副作用(Side Effect)

細(xì)說(shuō)ReactiveCocoa的冷信號(hào)與熱信號(hào)(二):為什么要區(qū)分冷熱信號(hào)提出了遂铡,如果冷信號(hào)中包含網(wǎng)絡(luò)請(qǐng)求肮疗,那么每次訂閱這個(gè)冷信號(hào)都會(huì)發(fā)送網(wǎng)絡(luò)請(qǐng)求,而且任何的信號(hào)轉(zhuǎn)換即是對(duì)原有的信號(hào)進(jìn)行訂閱從而產(chǎn)生新的信號(hào)

對(duì)于上述遇到的副作用扒接,有兩種解決辦法:

  1. 確保只對(duì)冷信號(hào)進(jìn)行一次訂閱
  2. 將冷信號(hào)轉(zhuǎn)換成特殊的熱信號(hào)

對(duì)于解決方法1伪货,對(duì)于一些簡(jiǎn)單的業(yè)務(wù)邏輯適用,獲得冷信號(hào)钾怔,訂閱冷信號(hào)碱呼,處理發(fā)出的事件。然而對(duì)于一些邏輯復(fù)雜的場(chǎng)景宗侦,需要對(duì)返回的信號(hào)進(jìn)行多次處理愚臀,就需要對(duì)冷信號(hào)進(jìn)行轉(zhuǎn)換,以避免副作用

4. 特殊的熱信號(hào)

為什么是特殊的熱信號(hào)矾利?特殊在哪姑裂?和普通的熱信號(hào)又要什么區(qū)別?在解釋這些問(wèn)題之前男旗,先看一個(gè)簡(jiǎn)單的實(shí)驗(yàn)

let signal = signalFromNetwork()
signal.observeNext {NSLog("subscriber get a next value: \($0)")}

這里假設(shè)signalFromNetwork()是發(fā)送網(wǎng)絡(luò)請(qǐng)求后獲得的一個(gè)熱信號(hào)signal(注意是熱信號(hào))舶斧,然后訂閱該信號(hào),這里簡(jiǎn)單地打印事件察皇。

但是茴厉,如果運(yùn)行這段代碼,并沒(méi)有輸出任何結(jié)果什荣。是因?yàn)榉祷氐男盘?hào)沒(méi)有發(fā)送任何next事件嗎矾缓?

func signalFromNetwork() -> Signal<String, NSError> {
    return Signal<String, NSError> {
        observer in
        NSLog("signal send hello")
        observer.sendNext("Hello")
        return nil
    }
}

實(shí)際上,返回的熱信號(hào)發(fā)送了一個(gè)next事件溃睹,但是訂閱者沒(méi)有收到而账。

我們把上面代碼稍微改一下

func signalFromNetwork() -> Signal<String, NSError> {
    return Signal<String, NSError> {
        observer in
        QueueScheduler.mainQueueScheduler.scheduleAfter(1) {
            NSLog("signal send hello")
            observer.sendNext("Hello")
        }
        return nil
    }
}

即,信號(hào)1s后再發(fā)送事件因篇,在看代碼的運(yùn)行結(jié)果

2016-04-20 14:59:45.150 ColdSignalAndHotSignal[35259:4813102] signal send hello
2016-04-20 14:59:45.153 ColdSignalAndHotSignal[35259:4813102] subscriber get a next value: Hello

這是我們可以看到有了輸出結(jié)果泞辐。這就說(shuō)明了之前訂閱者為什么沒(méi)有接收到事件笔横,因?yàn)樵谟嗛喺哂嗛啛嵝盘?hào)之前,熱信號(hào)就已經(jīng)發(fā)送了事件咐吼。而這次是因?yàn)闊嵝盘?hào)延遲了1s才發(fā)送事件吹缔,所以訂閱者才能接收到數(shù)據(jù)

雖然,我們可以讓生成信號(hào)的時(shí)候锯茄,延遲一段時(shí)間在發(fā)送事件厢塘,但RAC提供一種更好的熱信號(hào)來(lái)處理這種情況。

這就是RAC2中的RACReplaySubject肌幽,這種信號(hào)特點(diǎn)在于:

  1. 無(wú)論是否有訂閱者訂閱該信號(hào)晚碾,該信號(hào)都會(huì)發(fā)送事件,這點(diǎn)和熱信號(hào)一致
  2. 無(wú)論訂閱者何時(shí)訂閱信號(hào)喂急,訂閱者都能立即接收到該信號(hào)所發(fā)送的事件格嘁,這點(diǎn)和冷信號(hào)相似,但有很大的不同

而在RAC4中廊移,我們使用SignalProducer.buffer(Int)這個(gè)方法來(lái)代替RACReplaySubjectUsing SignalProducer.buffer instead of replaying

同樣通過(guò)一個(gè)實(shí)驗(yàn)來(lái)證明SignalProducer.bufferRACReplaySubject具有同樣的特點(diǎn)

let (producer, sink) = SignalProducer<String, NSError>.buffer(Int.max)
NSLog("producer start!")


//訂閱者1
producer.startWithNext {
    NSLog("Subscriber 1 get a next value: \($0) from producer")
}

//開(kāi)始發(fā)送第一個(gè)包
QueueScheduler.mainQueueScheduler.scheduleAfter(1) {
    NSLog("producer send package 1"); sink.sendNext("send package 1")
}

//發(fā)送第二個(gè)包
QueueScheduler.mainQueueScheduler.scheduleAfter(2) {
    NSLog("producer send package 2"); sink.sendNext("send package 2")
}

//訂閱者2
QueueScheduler.mainQueueScheduler.scheduleAfter(4) {
    producer.startWithNext {
        NSLog("Subscriber 2 get a next value: \($0) from producer")
    }
}

因?yàn)榇a和之前實(shí)驗(yàn)代碼相似糕簿,這里只簡(jiǎn)單解釋下:1

  1. 創(chuàng)建特殊的熱信號(hào),并在1s狡孔,4s后發(fā)送兩個(gè)包
  2. 在0s和1.5s時(shí)懂诗,訂閱者1、2訂閱了該信號(hào)

以下是輸出結(jié)果:

2016-04-20 15:31:23.821 ColdSignalAndHotSignal[35872:4955068] producer start!
2016-04-20 15:31:24.861 ColdSignalAndHotSignal[35872:4955068] producer send package 1
2016-04-20 15:31:24.863 ColdSignalAndHotSignal[35872:4955068] Subscriber 1 get a next value: send package 1 from producer
2016-04-20 15:31:26.037 ColdSignalAndHotSignal[35872:4955068] producer send package 2
2016-04-20 15:31:26.037 ColdSignalAndHotSignal[35872:4955068] Subscriber 1 get a next value: send package 2 from producer
2016-04-20 15:31:28.237 ColdSignalAndHotSignal[35872:4955068] Subscriber 2 get a next value: send package 1 from producer
2016-04-20 15:31:28.237 ColdSignalAndHotSignal[35872:4955068] Subscriber 2 get a next value: send package 2 from producer

來(lái)分析輸出結(jié)果的一些特點(diǎn):

  1. 所有事件苗膝,信號(hào)只發(fā)送了一次
  2. 訂閱者1是0s訂閱的殃恒,毫無(wú)疑問(wèn),訂閱者1可以接收到所有事件
  3. 訂閱者2是4s才訂閱的荚醒,而此時(shí)信號(hào)已經(jīng)發(fā)出了所有的事件芋类,如果是普通的熱信號(hào),訂閱者2是接受不到任何事件的界阁,但這里訂閱者2卻同時(shí)接收到了信號(hào)發(fā)送的所有事件侯繁,就像所有的事件緩存起來(lái)一樣

根據(jù)特點(diǎn),我們可以得到ReplaySubjectSingalProducer.buffer產(chǎn)生的信號(hào)的圖

特殊的熱信號(hào).png

而且這種信號(hào)的命名也很有意思泡躯,在RAC2中是Replay贮竟,代表事件可以重放。而在RAC4中是buffer较剃,代表事件被緩存起來(lái)

現(xiàn)在回到冷信號(hào)副作用的問(wèn)題上咕别,因?yàn)?code>buffer返回的信號(hào),具有熱信號(hào)的特點(diǎn)写穴,不會(huì)產(chǎn)生副作用惰拱。同時(shí)又能像冷信號(hào)一樣,確保所有的訂閱者都能接收到事件啊送。

現(xiàn)在將本節(jié)signalFromNetwork()作出一些更改

func signalFromNetwork() -> SignalProducer<String, NSError> {
    let (producer, sink) = SignalProducer<String, NSError>.buffer(Int.max)
    NSLog("signal send hello")
    sink.sendNext("Hello")
    return producer
}

然后來(lái)訂閱返回的信號(hào)

let signal = signalFromNetwork()
QueueScheduler.mainQueueScheduler.scheduleAfter(2) {
    NSLog("Subscriber 1")
    signal.startWithNext{NSLog("Subscriber get a next value: \($0)")}
}
QueueScheduler.mainQueueScheduler.scheduleAfter(4) {
    NSLog("Subscriber 2")
    signal.startWithNext{NSLog("subscriber 2 get a next value: \($0)")}
}

為了突出效果偿短,我們故意使用兩個(gè)訂閱者訂閱了該信號(hào)欣孤,并且一個(gè)延時(shí)到2s才訂閱喜颁,一個(gè)延時(shí)到4s才訂閱遣铝,來(lái)看下輸出結(jié)果:

2016-04-20 15:48:50.192 ColdSignalAndHotSignal[36260:5027885] signal send hello
2016-04-20 15:48:52.394 ColdSignalAndHotSignal[36260:5027885] Subscriber 1
2016-04-20 15:48:52.397 ColdSignalAndHotSignal[36260:5027885] Subscriber get a next value: Hello
2016-04-20 15:48:54.594 ColdSignalAndHotSignal[36260:5027885] Subscriber 2
2016-04-20 15:48:54.595 ColdSignalAndHotSignal[36260:5027885] subscriber 2 get a next value: Hello

和預(yù)期的一樣遮怜,無(wú)論有多少個(gè)訂閱者抽减,信號(hào)都只會(huì)發(fā)送一次事件,而且無(wú)論訂閱者多遲才訂閱該信號(hào)都能收到信號(hào)發(fā)送的事件车猬。

然而玻佩,有些情況下谐鼎,類似signalFromNetwork()這種方法是別人提供的笔链,而且返回的就是一個(gè)冷信號(hào)SignalProducer 這種情況段只,你可能無(wú)法修改signalFromNetwork()內(nèi)部代碼。那要如何處理這個(gè)冷信號(hào)卡乾,避免副作用呢翼悴?

在RAC4.0,SignalProducer添加了replayLazily這個(gè)方法幔妨,避免了冷信號(hào)的副作用 Added SignalProducer.replayLazily for multicasting

我們將signalFromNetwork()改成返回冷信號(hào)

func signalFromNetwork() -> SignalProducer<String, NSError> {
    let producer = SignalProducer<String, NSError> {
        observer, _ in
        NSLog("signal send hello")
        observer.sendNext("Hello")
    }
    return producer
}

而訂閱該信號(hào)的代碼如下:

let signal = signalFromNetwork().replayLazily(1)
QueueScheduler.mainQueueScheduler.scheduleAfter(2) {
    NSLog("Subscriber 1")
    signal.startWithNext{NSLog("Subscriber get a next value: \($0)")}
}
QueueScheduler.mainQueueScheduler.scheduleAfter(4) {
    NSLog("Subscriber 2")
    signal.startWithNext{NSLog("subscriber 2 get a next value: \($0)")}
}

只是在返回信號(hào)調(diào)用replayLazily方法,其余都不變

2016-04-20 16:11:54.223 ColdSignalAndHotSignal[36783:5133284] start
2016-04-20 16:11:56.423 ColdSignalAndHotSignal[36783:5133284] Subscriber 1
2016-04-20 16:11:56.429 ColdSignalAndHotSignal[36783:5133284] signal send hello
2016-04-20 16:11:56.429 ColdSignalAndHotSignal[36783:5133284] Subscriber get a next value: Hello
2016-04-20 16:11:58.623 ColdSignalAndHotSignal[36783:5133284] Subscriber 2
2016-04-20 16:11:58.623 ColdSignalAndHotSignal[36783:5133284] subscriber 2 get a next value: Hello

貌似和之前和輸出結(jié)果有點(diǎn)不一樣谍椅,忽略那個(gè)start吧误堡!只有Subscriber1signal send hello順序顛倒了,從時(shí)間上來(lái)看雏吭,信號(hào)發(fā)送事件的時(shí)間延遲了锁施。

5. bufferreplayLazily中的參數(shù)capacity

在使用這兩個(gè)方法時(shí),需要傳一個(gè)名為capacity參數(shù)杖们,那這個(gè)參數(shù)是什么意思呢悉抵?感興趣的同學(xué)可以先去看看官方文檔是怎么解釋的。

這里通過(guò)小實(shí)驗(yàn)來(lái)研究這個(gè)參數(shù)的意義

    let (producer, sink) = SignalProducer<String, NSError>.buffer(1)
    sink.sendNext("A")
    sink.sendNext("B")
    sink.sendNext("C")
    
    QueueScheduler.mainQueueScheduler.scheduleAfter(2) {
        producer.startWithNext{print($0)}
    }

很簡(jiǎn)單的一段代碼摘完,信號(hào)發(fā)送三個(gè)next事件姥饰,2s后,訂閱者訂閱該信號(hào)孝治。

如果你以為輸出的是A B C列粪,那就請(qǐng)看實(shí)際運(yùn)行結(jié)果

C

貌似只輸出一個(gè)C,那A和B呢

接下來(lái)谈飒,我們把buffer(1)改成buffer(3)

在看輸出結(jié)果

A
B
C

到這就應(yīng)該明白capacity的含義岂座,就是指SignalProducer為訂閱者緩存多少個(gè)事件,如果發(fā)送事件數(shù)超過(guò)緩存容量杭措,則先發(fā)送的事件會(huì)被后發(fā)送的事件覆蓋费什,這也解釋了為什么當(dāng)capacity=1時(shí),只輸出C

同樣replayLazily中的capacity參數(shù)也是同樣的含義

但是手素,如果將上面的例子改成replayLazily鸳址,輸出結(jié)果會(huì)有略微的不同赘那,自己分析原因吧

圖片引用自:細(xì)說(shuō)ReactiveCocoa的冷信號(hào)與熱信號(hào)(三):怎么處理冷信號(hào)與熱信號(hào)

`

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市氯质,隨后出現(xiàn)的幾起案子募舟,更是在濱河造成了極大的恐慌,老刑警劉巖闻察,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拱礁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡辕漂,警方通過(guò)查閱死者的電腦和手機(jī)呢灶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)钉嘹,“玉大人鸯乃,你說(shuō)我怎么就攤上這事“匣粒” “怎么了缨睡?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)陈辱。 經(jīng)常有香客問(wèn)我奖年,道長(zhǎng),這世上最難降的妖魔是什么沛贪? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任陋守,我火速辦了婚禮,結(jié)果婚禮上利赋,老公的妹妹穿的比我還像新娘水评。我一直安慰自己,他們只是感情好媚送,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布中燥。 她就那樣靜靜地躺著,像睡著了一般季希。 火紅的嫁衣襯著肌膚如雪褪那。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天式塌,我揣著相機(jī)與錄音博敬,去河邊找鬼。 笑死峰尝,一個(gè)胖子當(dāng)著我的面吹牛偏窝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼祭往,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼伦意!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起硼补,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤驮肉,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后已骇,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體离钝,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年褪储,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了卵渴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鲤竹,死狀恐怖浪读,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情辛藻,我是刑警寧澤碘橘,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站揩尸,受9級(jí)特大地震影響蛹屿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜岩榆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坟瓢。 院中可真熱鬧勇边,春花似錦、人聲如沸折联。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)诚镰。三九已至奕坟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間清笨,已是汗流浹背月杉。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抠艾,地道東北人苛萎。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親腌歉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蛙酪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容