3.RAC之RACReplaySubject
2017-05-31 本文已影响137人
Terrnce
我们直接看RACReplaySubject头文件,可以看到RACReplaySubject是继承自RACSubject。
RACReplaySubject创建信号的两种方式
/// 第一种方式
RACReplaySubject *subject = [RACReplaySubject subject];
/// 第二种方式,通过设置capacity来限定它接收事件的数量,这个方法下面会说到
RACReplaySubject *replaySubject = [RACReplaySubject replaySubjectWithCapacity:2];
查看RACReplaySubject底层是如何实现订阅信号的
- 第①步:还是创建一个订阅者RACSubscriber,保存nextBlock
- 第②步:看下图
这里可以看到,虽然RACReplaySubject 是继承于RACSubject的,但是他们的实现订阅的方式却是不一样的。
RACSubject通过将创建的订阅者RACSubscriber保存到一个订阅者数组subscribers中去,然后发送信号sendNext的时候通过遍历订阅者subscribers取得每一个订阅者RACSubscriber,然后让订阅者去执行nextBlock。
RACReplaySubject 通过遍历 一个self.valuesReceived数组,让新创建的订阅者RACSubscriber 去执行 sendNext操作。这里也就是说RACReplaySubject 在执行订阅操作的时候就已经能够发送信号了,这个跟前面学的RACSignal和RACSubject不一样。
那么,这个self.valuesReceived又是什么呢?
这个要从RACReplaySubject头文件里面一个类方法开始看起
/// Creates a new replay subject with the given capacity. A capacity of
/// RACReplaySubjectUnlimitedCapacity means values are never trimmed.
/// 通过设置capacity来限定它接收重接收事件的数量
+ (instancetype)replaySubjectWithCapacity:(NSUInteger)capacity;
看一下他的实现
屏幕快照 2017-05-30 下午7.45.36.png很简单,其实就是通过传入的capacity去创建一个指定长度的数组。
查看RACReplaySubject底层是如何实现发送信号的
屏幕快照 2017-05-30 下午8.03.31.png使用例子
/// 设置接受事件的数量为2
RACReplaySubject *replaySubject = [RACReplaySubject replaySubjectWithCapacity:2];
[replaySubject sendNext:@"hello world”]; //这句打印会被移除,原因是因为前面设置了接收事件的数量为2
[replaySubject sendNext:@"rac"];
[replaySubject sendNext:@"text 3"];
[replaySubject subscribeNext:^(id x) {
NSLog(@"第一个订阅者接收到的数据%@",x);
}];
[replaySubject subscribeNext:^(id x) {
NSLog(@"第二个订阅者接收到的数据%@",x);
}];
打印结果:
2017-05-30 20:38:25.890 RACDemo[3182:1376598] 第一个订阅者接收到的数据rac
2017-05-30 20:38:25.891 RACDemo[3182:1376598] 第一个订阅者接收到的数据text 3
2017-05-30 20:38:25.891 RACDemo[3182:1376598] 第二个订阅者接收到的数据rac
2017-05-30 20:38:25.891 RACDemo[3182:1376598] 第二个订阅者接收到的数据text 3
假如你这里把 subscribeNext 操作放到 sendNext 操作前面,那么效果就跟RACSubject一样,你设置的replaySubjectWithCapacity:2 不起任何作用。
总结:
- RACReplaySubject 是 RACSubject的子类
- RACReplaySubject 可以先sendNext ,再执行 subscribeNext。
- RACReplaySubject 可以通过 replaySubjectWithCapacity:初始化方法设置接受事件数量。