(這篇文章原來發布在 csdn ,如今 blog 遷移過來,並用 Markdown 從新排版以及修改).net
racsignal 的信號有冷熱之分,簡單來講所謂冷信號能夠理解爲被動的,只有當有訂閱者的狀況下,纔會發佈消息,且每訂閱一次,重複發一次消息。而熱信號則不依賴與訂閱者,當它須要發消息的時候,不論有沒有訂閱者,都會發送。code
冷信號以下:blog
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { NSLog(@"send"); [subscriber sendNext:@"sender"]; [subscriber sendCompleted]; return nil; }]; NSLog(@"start"); [[RACScheduler mainThreadScheduler] afterDelay:0.5 schedule:^{ [signal subscribeNext:^(id x) { NSLog(@"Subscriber 1 recveive: %@", x); }]; }]; [[RACScheduler mainThreadScheduler] afterDelay:1 schedule:^{ [signal subscribeNext:^(id x) { NSLog(@"Subscriber 2 recveive: %@", x); }]; }];
其輸出以下文檔
2016-02-18 21:00:11.190 ReactiveExample[46349:4307881] start 2016-02-18 21:00:11.733 ReactiveExample[46349:4307881] send 2016-02-18 21:00:11.733 ReactiveExample[46349:4307881] Subscriber 1 recveive: sender 2016-02-18 21:00:12.291 ReactiveExample[46349:4307881] send 2016-02-18 21:00:12.291 ReactiveExample[46349:4307881] Subscriber 2 recveive: sender
可見,只有有訂閱者的狀況下,才發送消息,而且每來一個訂閱者,從新發生一次,冷信號是沒有狀態的。get
而熱信號是有狀態的,能夠將上述冷信號轉化爲熱信號,代碼以下ast
RACSignal *signal = [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { NSLog(@"send"); [subscriber sendNext:@"sender"]; [subscriber sendCompleted]; return nil; }] multicast:[RACSubject subject]] autoconnect]; NSLog(@"start"); [[RACScheduler mainThreadScheduler] afterDelay:0.5 schedule:^{ [signal subscribeNext:^(id x) { NSLog(@"Subscriber 1 recveive: %@", x); }]; }]; [[RACScheduler mainThreadScheduler] afterDelay:1 schedule:^{ [signal subscribeNext:^(id x) { NSLog(@"Subscriber 2 recveive: %@", x); }]; }];
,這裏的signal是熱信號,它會在第一次被訂閱的時候被激活,其輸出以下co
2016-02-19 19:59:13.611 ReactiveExample[70352:6183597] start 2016-02-19 19:59:14.140 ReactiveExample[70352:6183597] send 2016-02-19 19:59:14.141 ReactiveExample[70352:6183597] Subscriber 1 recveive: sender
可見,第二次訂閱並無再次觸發 signal 信號,且因爲 signal 是在啓動後 0.5s 發出的信號,所以啓動後 1s 訂閱者錯過了 signal 發出的消息。cas
固然,熱信號其實也有多種類型,上面冷信號轉熱信號是經過 RACSubject 轉化,下面也能夠經過 RACReplaySubject 來轉換let
RACSignal *signal = [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { NSLog(@"send"); [subscriber sendNext:@"sender"]; [subscriber sendCompleted]; return nil; }] multicast:[RACReplaySubject subject]] autoconnect]; NSLog(@"start"); [[RACScheduler mainThreadScheduler] afterDelay:0.5 schedule:^{ [signal subscribeNext:^(id x) { NSLog(@"Subscriber 1 recveive: %@", x); }]; }]; [[RACScheduler mainThreadScheduler] afterDelay:1 schedule:^{ [signal subscribeNext:^(id x) { NSLog(@"Subscriber 2 recveive: %@", x); }]; }];
輸出以下,消息
2016-02-19 20:13:56.996 ReactiveExample[70544:6255982] start 2016-02-19 20:13:57.545 ReactiveExample[70544:6255982] send 2016-02-19 20:13:57.545 ReactiveExample[70544:6255982] Subscriber 1 recveive: sender 2016-02-19 20:13:58.070 ReactiveExample[70544:6255982] Subscriber 2 recveive: sender
對比經過 RACSubject 轉化的輸出結果能夠發現,這裏 0.5s ,以及 1s 訂閱的兩個訂閱者都收到了 signal 發出的信號。RACReplaySubject 具備緩衝功能,可以收到歷史信息。
說到這裏,同窗們可能會疑惑了,那 RACReplaySubject 跟冷信號有什麼區別呢?細心的同窗會發現,在冷信號代碼示例中,NSLog(@"send") ;輸出了兩次,而在 RACReplaySubject 實例代碼中 NSLog(@"send");只輸出了一次。這就是區別了,冷信號會重複觸發 signal 裏面的邏輯,而 RACReplaySubject 只是重複發出信號而已。固然冷信號轉熱信號的方式還有多種,有興趣的同窗能夠研究一下其官網文檔