RACSignal,RACSubject,RACReplaySu
2018-04-24 本文已影响30人
哦呵呵y
系列文章
RACSignal,RACSubject,RACReplaySubject
RAC bind
RAC Merge flatten
RACMulticastConnection
RAC switchToLatest
一、 RACSignal信号类
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:nil];
return nil;
}];
[signal subscribeNext:^(id _Nullable x) {
}];
...
// 订阅
RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
return [self subscribe:o];
// RACDynamicSignal subscribe 内部实现
RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
if (self.didSubscribe != NULL) {
RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
RACDisposable *innerDisposable = self.didSubscribe(subscriber);
[disposable addDisposable:innerDisposable];
}]; // 这里传入的block会立即调用。
[disposable addDisposable:schedulingDisposable];
}
return disposable;
- 创建信号, 生成
RACDynamicSignal
,将传入的block 保存到信号的didSubscribe
Block中。 - 订阅信号,生成
RACSubscriber
并保存nextBlock
, 然后调用信号类的subscribe
方法设置订阅者,方法内部会调用信号对象中的didSubscribe
block。 - 发送信号,
didSubscribe
被调用后,可以获取到相应的订阅者,调用订阅者的sendNext
方法会立马调用订阅信号时传入的nextBlock
; - 订阅时会触发创建时的block,而创建时的block内部会获取相应的订阅者,做完相应操作后,调用订阅者发送信号,触发订阅是创建的block;
二、RACSubject:信号提供者,自己可以充当信号,又能发送信号。
RACSubject *subject = [RACSubject subject];
[subject subscribeNext:^(id _Nullable x) {
}];
[subject sendNext:@""];
...
// RACSubject subscribe 内部实现
RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
NSMutableArray *subscribers = self.subscribers;
@synchronized (subscribers) {
[subscribers addObject:subscriber];
}
[disposable addDisposable:[RACDisposable disposableWithBlock:^{
@synchronized (subscribers) {
// Since newer subscribers are generally shorter-lived, search
// starting from the end of the list.
NSUInteger index = [subscribers indexOfObjectWithOptions:NSEnumerationReverse passingTest:^ BOOL (id<RACSubscriber> obj, NSUInteger index, BOOL *stop) {
return obj == subscriber;
}];
if (index != NSNotFound) [subscribers removeObjectAtIndex:index];
}
}]];
return disposable;
...
// 发送信号
[self enumerateSubscribersUsingBlock:^(id<RACSubscriber> subscriber) {
[subscriber sendNext:value];
}];
- 创建信号,生成一个数组用来保存订阅者
- 订阅信号,生成订阅者,将订阅者保存到数组中
- 发送信号,遍历数组,将消息发送到每一个订阅者。
三、RACReplaySubject 继承自RACSubject
// RACReplaySubject subscribe 内部实现
RACCompoundDisposable *compoundDisposable = [RACCompoundDisposable compoundDisposable];
RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
@synchronized (self) {
for (id value in self.valuesReceived) {
if (compoundDisposable.disposed) return;
[subscriber sendNext:(value == RACTupleNil.tupleNil ? nil : value)];
}
if (compoundDisposable.disposed) return;
if (self.hasCompleted) {
[subscriber sendCompleted];
} else if (self.hasError) {
[subscriber sendError:self.error];
} else {
RACDisposable *subscriptionDisposable = [super subscribe:subscriber];
[compoundDisposable addDisposable:subscriptionDisposable];
}
}
}];
[compoundDisposable addDisposable:schedulingDisposable];
return compoundDisposable;
- 创建信号,在父类的基础上同时创建一个数组,用来保存历史消息
- 订阅信号,重写
subscribe
方法,先对当前订阅者发送所有历史消息,然后在将订阅者添加到数组中。 - 发送信号,同父类,遍历订阅者,发送消息。