ReactiveCocoa-冷信号和热信号的理解
冷信号
冷信号:只有有订阅者的时候才会发出信号,一对一,如果有其他的订阅者订阅会重新完整的发送信号,给订阅者发送消息则一定会收到。
文字解释或许不直观,看下如下例子:
//冷信号
- (void)coldSign{
RACSignal * signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSLog(@"发送信号");
[subscriber sendNext:@"1"];
[subscriber sendNext:@"2"];
[subscriber sendNext:@"3"];
[subscriber sendCompleted];
return nil;
}];
[signal subscribeNext:^(id x) {
NSLog(@"sign1 :%@",x);
}];
[signal subscribeNext:^(id x) {
NSLog(@"sign2 :%@",x);
}];
[signal subscribeNext:^(id x) {
NSLog(@"sign3 :%@",x);
}];
}
//打印结果
2018-08-07 14:54:38.325958+0800 ReactiveCocoaDemo[10525:226732] 发送信号
2018-08-07 14:54:38.326174+0800 ReactiveCocoaDemo[10525:226732] sign1 :1
2018-08-07 14:54:38.326294+0800 ReactiveCocoaDemo[10525:226732] sign1 :2
2018-08-07 14:54:38.326445+0800 ReactiveCocoaDemo[10525:226732] sign1 :3
2018-08-07 14:54:38.326763+0800 ReactiveCocoaDemo[10525:226732] 发送信号
2018-08-07 14:54:38.326975+0800 ReactiveCocoaDemo[10525:226732] sign2 :1
2018-08-07 14:54:38.327107+0800 ReactiveCocoaDemo[10525:226732] sign2 :2
2018-08-07 14:54:38.327211+0800 ReactiveCocoaDemo[10525:226732] sign2 :3
2018-08-07 14:54:38.327365+0800 ReactiveCocoaDemo[10525:226732] 发送信号
2018-08-07 14:54:38.327476+0800 ReactiveCocoaDemo[10525:226732] sign3 :1
2018-08-07 14:54:38.327615+0800 ReactiveCocoaDemo[10525:226732] sign3 :2
2018-08-07 14:54:38.327720+0800 ReactiveCocoaDemo[10525:226732] sign3 :3
我们创建了一个信号signal,并且订阅了3次,可以看到每订阅一次信号就会发送一次,相应的订阅者就会收到一次消息。从这里可以看出冷信号是没有时效性的,只要订阅就会发送。在实际使用中我们通常用冷信号来回调网络请求,那么如果我们订阅多次则会发送多次网络请求,这也是长犯的错误。
热信号
热信号:不在乎是否有订阅者,一对多,如果发送当时有订阅者,就会同时接收到信号,如果没有就不会接收到消息,给订阅者发送消息不一定会收到。
- (void)hotSign{
RACMulticastConnection * connection = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[[RACScheduler mainThreadScheduler] afterDelay:1 schedule:^{
[subscriber sendNext: @"1"];
}];
[[RACScheduler mainThreadScheduler] afterDelay:2 schedule:^{
[subscriber sendNext: @"2"];
}];
[[RACScheduler mainThreadScheduler] afterDelay:3 schedule:^{
[subscriber sendNext: @"3"];
}];
[[RACScheduler mainThreadScheduler] afterDelay:4 schedule:^{
[subscriber sendNext: @"4"];
}];
return nil;
}] publish];
[connection connect];
RACSignal * signal = connection.signal;
[[RACScheduler mainThreadScheduler] afterDelay:1.1 schedule:^{
[signal subscribeNext:^(id x) {
NSLog(@"sign1 :%@",x);
}];
}];
[[RACScheduler mainThreadScheduler] afterDelay:2.1 schedule:^{
[signal subscribeNext:^(id x) {
NSLog(@"sign2 :%@",x);
}];
}];
}
2018-08-07 15:09:41.783441+0800 ReactiveCocoaDemo[10747:236633] sign1 :2
2018-08-07 15:09:42.780398+0800 ReactiveCocoaDemo[10747:236633] sign1 :3
2018-08-07 15:09:42.780704+0800 ReactiveCocoaDemo[10747:236633] sign2 :3
2018-08-07 15:09:43.783254+0800 ReactiveCocoaDemo[10747:236633] sign1 :4
2018-08-07 15:09:43.783594+0800 ReactiveCocoaDemo[10747:236633] sign2 :4
这个例子中先不要管RACMulticastConnection是干啥的,反正这一大堆就是创建了一个热信号,并且分别在1s、2s、3s、4s的时候发送了型号,有两个订阅者,分别在1.1s、1.2s的时候订阅了这个信号。看打印信息我们知道,signal 1收到了消息2、3、4,signal2收到了3、4。我们可以这道热信号是有时效性的,与你是否订阅无关,没人订阅也会发送,丢失不补,不惯毛病,跟Cocoa中的通知十分相似。
思考
那我们思考一下:如果把上面的例子从热信号换成冷信号会怎么样呢?
- (void)coldSign{
RACSignal * signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSLog(@"发送信号");
[[RACScheduler mainThreadScheduler] afterDelay:1 schedule:^{
[subscriber sendNext: @"1"];
}];
[[RACScheduler mainThreadScheduler] afterDelay:2 schedule:^{
[subscriber sendNext: @"2"];
}];
[[RACScheduler mainThreadScheduler] afterDelay:3 schedule:^{
[subscriber sendNext: @"3"];
}];
[[RACScheduler mainThreadScheduler] afterDelay:4 schedule:^{
[subscriber sendNext: @"4"];
}];
return nil;
}];
[signal subscribeNext:^(id x) {
NSLog(@"sign1 :%@",x);
}];
[signal subscribeNext:^(id x) {
NSLog(@"sign2 :%@",x);
}];
}
2018-08-07 15:16:57.946886+0800 ReactiveCocoaDemo[10872:241848] 发送信号
2018-08-07 15:16:57.947319+0800 ReactiveCocoaDemo[10872:241848] 发送信号
2018-08-07 15:16:58.951425+0800 ReactiveCocoaDemo[10872:241848] sign1 :1
2018-08-07 15:16:58.951780+0800 ReactiveCocoaDemo[10872:241848] sign2 :1
2018-08-07 15:16:59.948999+0800 ReactiveCocoaDemo[10872:241848] sign1 :2
2018-08-07 15:16:59.949182+0800 ReactiveCocoaDemo[10872:241848] sign2 :2
2018-08-07 15:17:00.949210+0800 ReactiveCocoaDemo[10872:241848] sign1 :3
2018-08-07 15:17:00.949435+0800 ReactiveCocoaDemo[10872:241848] sign2 :3
2018-08-07 15:17:01.947757+0800 ReactiveCocoaDemo[10872:241848] sign1 :4
2018-08-07 15:17:01.948141+0800 ReactiveCocoaDemo[10872:241848] sign2 :4
可以看出冷信号订阅即发送,而这个操作并不是同步的。
总结:
为了更好的理解可以做一个比喻:
把整个过程比喻成订餐,有两家饭店 冷冰冰饭店、热乎乎饭店分别采用了不同的策略应对订餐这项服务。
冷冰冰饭店:我们全心全意为顾客服务,只要有人订餐,我们就会马上做好给顾客送过去的!!,所以冷冰冰饭店的订餐过程是,收到订阅就会做饭送餐,收到一份就重复一次这个过程
热乎乎饭店:我才不管你是谁呢,我们只在11点的时候送餐,之前接受预定,11点之后定的不送!!,热乎乎的订餐过程是我一天就做这么多饭,等到11点的时候,看下有多少人订餐,一起送过去
不知道大家是否看懂了呢,看懂了点赞留言哦