FRP的核心是信号,信号在ReactiveCocoa(以下简称RAC)中是通过RACSignal来表示的,信号是数据流,可以被绑定和传递。
引用大神博客里的解释:“可以把信号想象成水龙头,只不过里面不是水,而是玻璃球(value),直径跟水管的内径一样,这样就能保证玻璃球是依次排列,不会出现并排的情况(数据都是线性处理的,不会出现并发情况)。水龙头的开关默认是关的,除非有了接收方(subscriber),才会打开。这样只要有新的玻璃球进来,就会自动传送给接收方。可以在水龙头上加一个过滤嘴(filter),不符合的不让通过,也可以加一个改动装置,把球改变成符合自己的需求(map)。也可以把多个水龙头合并成一个新的水龙头(combineLatest:reduce:),这样只要其中的一个水龙头有玻璃球出来,这个新合并的水龙头就会得到这个球。
RAC统一了对KVO、UI Event、Network request、Async work的处理,因为它们本质上都是值的变化(Values over time)。”。
1.工作原理
信号源是最核心的部分,其它所有组件都是围绕它运作的。
ReactiveCocoa最简单的工作过程就是
创建信号——订阅信号——发送信号。
2.组成部分
ReactiveCocoa主要包含四个组件:
信号源:RACStream 及其子类;
订阅者:RACSubscriber 的实现类及其子类;
调度器:RACScheduler 及其子类;
清洁工:RACDisposable 及其子类。
3.冷信号与热信号:
信号分为冷信号与热信号;
Hot Observable是主动的,尽管你并没有订阅事件,但是它会时刻推送,就像鼠标移动;而Cold Observable是被动的,只有当你订阅的时候,它才会发布消息。
Hot Observable可以有多个订阅者,是一对多,集合可以与订阅者共享信息;而Cold Observable只能一对一,当有不同的订阅者,消息是重新完整发送。
实例代码测试
//热信号
RACSubject *subject = [RACSubject subject];
[subject sendNext:@1];
[[RACScheduler mainThreadScheduler] afterDelay:0.5 schedule:^{
[subject sendNext:@2];
}];
[[RACScheduler mainThreadScheduler] afterDelay:2 schedule:^{
[subject sendNext:@3];
}];
[[RACScheduler mainThreadScheduler] afterDelay:0.1 schedule:^{
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"subject1接收到了%@",x); //0.1秒后subject1订阅了
}];
}];
[[RACScheduler mainThreadScheduler] afterDelay:1 schedule:^{
[subject subscribeNext:^(id x) {
NSLog(@"subject2接收到了%@",x); //1秒后subject2订阅了 }];
}];
}];
2019-04-08 10:36:38.888186+0800 TestDemo[7056:149752] subject1接收到了2
2019-04-08 10:36:40.444486+0800 TestDemo[7056:149752] subject1接收到了3
2019-04-08 10:36:40.444675+0800 TestDemo[7056:149752] subject2接收到了3
//冷信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
[subscriber sendNext:@1];
[[RACScheduler mainThreadScheduler] afterDelay:0.5 schedule:^{
[subscriber sendNext:@2];
}];
[[RACScheduler mainThreadScheduler] afterDelay:2 schedule:^{
[subscriber sendNext:@3];
}]; return nil;
}];
[[RACScheduler mainThreadScheduler] afterDelay:0.1 schedule:^{
[signal subscribeNext:^(id x) {
NSLog(@"signal1接收到了%@", x);
}];
}];
[[RACScheduler mainThreadScheduler] afterDelay:1 schedule:^{
[signal subscribeNext:^(id x) {
NSLog(@"signal2接收到了%@", x);
}];
}];
2019-04-08 10:36:38.452558+0800 TestDemo[7056:149752] signal1接收到了1
2019-04-08 10:36:38.985971+0800 TestDemo[7056:149752] signal1接收到了2
2019-04-08 10:36:39.384237+0800 TestDemo[7056:149752] signal2接收到了1
2019-04-08 10:36:39.934146+0800 TestDemo[7056:149752] signal2接收到了2
2019-04-08 10:36:40.452848+0800 TestDemo[7056:149752] signal1接收到了3
2019-04-08 10:36:41.384718+0800 TestDemo[7056:149752] signal2接收到了3
结论:
热信号是主动的,即使你没有订阅事件,它仍然会时刻推送。如上面没有接收到的信号都是因为在没有订阅者的时候,它也会推送出去。而冷信号是被动的,只有当你订阅的时候,它才会发送消息。如第二段代码,订阅后才把信号推送出去。
热信号可以有多个订阅者,是一对多,信号可以与订阅者共享信息。如第一段代码,订阅者1和订阅者2是共享的,他们都能在同一时间接收到3这个值。而冷信号只能一对一,当有不同的订阅者,消息会从新完整发送。如第一个例子,我们可以观察到两个订阅者没有联系,都是基于各自的订阅时间开始接收消息的。
参考 :https://limboy.me/tech/2013/06/19/frp-reactivecocoa.html