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 只是重复发出信号而已。固然冷信号转热信号的方式还有多种,有兴趣的同窗能够研究一下其官网文档

相关文章
相关标签/搜索