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