热信号RACSubject
RACSubject
是RACSignal
的子类,RACSubject
实现了RACSubscriber
协议,RACSubject
的订阅过程和RACSignal
的区别很大,subject内部有一个可变数组subscribers
,这个数组保存了所有的订阅者,所以当执行sendNext
操作时,所有已经订阅的都能收到消息
RACSubject *subject = [RACSubject subject];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"1st subject: %@",x);
}];
[subject sendNext:@"1"];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"2st subject: %@",x);
}];
[subject sendNext:@"2"];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"3st subject: %@",x);
}];
[subject sendNext:@"3"];
[subject sendCompleted];
log信息如下
1st subject: 1
1st subject: 2
2st subject: 2
1st subject: 3
2st subject: 3
3st subject: 3
订阅的内部实现
- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
NSMutableArray *subscribers = self.subscribers;
@synchronized (subscribers) {
[subscribers addObject:subscriber];
}
return disposable;
}
sendNext的操作其实是一个遍历subscribers
数组的过程
- (void)sendNext:(id)value {
[self enumerateSubscribersUsingBlock:^(id<RACSubscriber> subscriber) {
[subscriber sendNext:value];
}];
}
子类RACBehaviorSubject和RACReplaySubject
RACBehaviorSubject
在订阅时会向订阅者发送最新的消息,RACReplaySubject
在订阅之后可以重新发送之前的所有消息序列。
- RACBehaviorSubject
它里面有个currentValue
变量,每次执行sendNext的时候currentValue
会被替换成当前的value,订阅的时候会执行[subscriber sendNext:self.currentValue]
,所以当前订阅者会收到最近的一条消息,还有当前的消息。因为sendNext:(id)value
方法执行了[super sendNext:value]
,所以之前的订阅者也能收到当前消息 ,还用上面的代码演示
RACBehaviorSubject *subject = [RACBehaviorSubject subject];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"1st subject: %@",x);
}];
[subject sendNext:@"1"];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"2st subject: %@",x);
}];
[subject sendNext:@"2"];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"3st subject: %@",x);
}];
[subject sendNext:@"3"];
[subject sendCompleted];
log信息如下
1st subject: (null)
1st subject: 1
2st subject: 1
1st subject: 2
2st subject: 2
3st subject: 2
1st subject: 3
2st subject: 3
3st subject: 3
- RACReplaySubject
它里面有个valuesReceived
变量,用来保存曾经发送过得消息值,每次订阅的时候会触发遍历
for (id value in self.valuesReceived) {
if (compoundDisposable.disposed) return;
[subscriber sendNext:(value == RACTupleNil.tupleNil ? nil : value)];
}
这样当前的订阅者就会收到之前的消息
同时sendNext
操作调用super操作,发送当前消息给之前的订阅者,演示代码
RACReplaySubject *subject = [RACReplaySubject subject];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"1st subject: %@",x);
}];
[subject sendNext:@"1"];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"2st subject: %@",x);
}];
[subject sendNext:@"2"];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"3st subject: %@",x);
}];
[subject sendNext:@"3"];
[subject sendCompleted];
log信息如下
1st subject: 1
2st subject: 1
1st subject: 2
2st subject: 2
3st subject: 1
3st subject: 2
1st subject: 3
2st subject: 3
3st subject: 3