rac初識之冷熱信號

(這篇文章原來發布在 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 只是重複發出信號而已。固然冷信號轉熱信號的方式還有多種,有興趣的同窗能夠研究一下其官網文檔

相關文章
相關標籤/搜索