rac初识之冷热信号

(这篇文章原来发布在 csdn ,现在 blog 迁移过来,并用 Markdown 重新排版以及修改)

racsignal 的信号有冷热之分,简单来说所谓冷信号可以理解为被动的,只有当有订阅者的情况下,才会发布消息,且每订阅一次,重复发一次消息。而热信号则不依赖与订阅者,当它需要发消息的时候,不论有没有订阅者,都会发送。

冷信号如下:

RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id 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] start2016-02-18 21:00:11.733 ReactiveExample[46349:4307881] send2016-02-18 21:00:11.733 ReactiveExample[46349:4307881] Subscriber 1 recveive: sender2016-02-18 21:00:12.291 ReactiveExample[46349:4307881] send2016-02-18 21:00:12.291 ReactiveExample[46349:4307881] Subscriber 2 recveive: sender

可见,只有有订阅者的情况下,才发送消息,并且每来一个订阅者,重新发生一次,冷信号是没有状态的。

而热信号是有状态的,可以将上述冷信号转化为热信号,代码如下

RACSignal *signal = [[[RACSignal createSignal:^RACDisposable *(id 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是热信号,它会在第一次被订阅的时候被激活,其输出如下

2016-02-19 19:59:13.611 ReactiveExample[70352:6183597] start2016-02-19 19:59:14.140 ReactiveExample[70352:6183597] send2016-02-19 19:59:14.141 ReactiveExample[70352:6183597] Subscriber 1 recveive: sender

可见,第二次订阅并没有再次触发 signal 信号,且由于 signal 是在启动后 0.5s 发出的信号,因此启动后 1s 订阅者错过了 signal 发出的消息。

当然,热信号其实也有多种类型,上面冷信号转热信号是通过 RACSubject 转化,下面也可以通过 RACReplaySubject 来转换

RACSignal *signal = [[[RACSignal createSignal:^RACDisposable *(id 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] start2016-02-19 20:13:57.545 ReactiveExample[70544:6255982] send2016-02-19 20:13:57.545 ReactiveExample[70544:6255982] Subscriber 1 recveive: sender2016-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 只是重复发出信号而已。当然冷信号转热信号的方式还有多种,有兴趣的同学可以研究一下其官网文档

关键字:xcode

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部