RACSignal 信号类 信号类本身并不具备发送消息的能力,而是通过subscriber来发送信息的。
RACSignal 创建信号
subscriber 发送信息
RACSignal 通过subscribeNext订阅信号
//1、
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
NSLog(@"创建了一个信号");
//发送信息
[subscriber sendNext:@"hello world"];
return [RACDisposable disposableWithBlock:^{
NSLog(@"销毁了");
}];
}];
//2、订阅信号量
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
第一步RACSignal 创建信号
RACSignal创建信号解析(进入RAC源码可见,创建RACSignal信号其实是创建RACDynamicSignal且将本身需要执行的block也一并传递过去了):
+ (RACSignal *)createSignal:(RACDisposable * (^)(id subscriber))didSubscribe {
return [RACDynamicSignal createSignal:didSubscribe];
}
+ (RACSignal *)createSignal:(RACDisposable * (^)(id subscriber))didSubscribe {
RACDynamicSignal *signal = [[self alloc] init];
//从RACSignal中传递过来的didSubscribe
signal->_didSubscribe = [didSubscribe copy];
return [signal setNameWithFormat:@"+createSignal:"];
}
第一步创建的流程图如下:
那我们什么时候调用到didSubscirbe这个block呢??带着这个疑问往下继续深入探讨后续代码。
第二步订阅信号
既然我们是创建了信号,肯定要订阅它,所以我们要先执行订阅信号的操作解析
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"订阅了: %@",x);
}];
这是订阅信号的操作,具体内容需要进入到RAC源码中:
- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
NSCParameterAssert(nextBlock != NULL);
//在订阅的操作中,创建了一个RACSubscriber类(订阅者),并将订阅block传递进去,保存了nextBlock这个block
RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
//创建完RACSubscriber后,调用subscribe,这里需要注意的是,因为我们创建的RACDynamicSignal,所以其实这里本质是调用的RACDynamicSignal subscribe:o
return [self subscribe:o];
}
创建订阅者 并保存了nextBlock
+ (instancetype)subscriberWithNext:(void (^)(id x))next error:(void (^)(NSError *error))error completed:(void (^)(void))completed {
RACSubscriber *subscriber = [[self alloc] init];
subscriber->_next = [next copy];
subscriber->_error = [error copy];
subscriber->_completed = [completed copy];
return subscriber;
}
调用RACDynamicSignal subscribe
- (RACDisposable *)subscribe:(id)subscriber {
NSCParameterAssert(subscriber != nil);
RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
//这里判断didSubcribe是否为空
if (self.didSubscribe != NULL) {
//这里就在调用didSubscribe方法,并且把刚才传入的subscriber调用出去
RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
//调用创建信号时候的didSubscribe这个block的内容
RACDisposable *innerDisposable = self.didSubscribe(subscriber);
[disposable addDisposable:innerDisposable];
}];
[disposable addDisposable:schedulingDisposable];
}
return disposable;
}
第二步流程图如下:
第三步 发送信息调用订阅中的nextBlock块代码
RACSignal 通过subscribeNext订阅信号
//1、
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
NSLog(@"创建了一个信号");
//发送信息
[subscriber sendNext:@"hello world"];
return [RACDisposable disposableWithBlock:^{
NSLog(@"销毁了");
}];
}];
//2、订阅信号量
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
通过sendNext 发送信息内容而后调用nextBlock块,具体代码解析:
- (void)sendNext:(id)value {
@synchronized (self) {
void (^nextBlock)(id) = [self.next copy];
if (nextBlock == nil) return;
nextBlock(value);
}
}
这里主要就是做了一件事,如果nextblock不为空就把传进来传value原封不动的调用出去。 而这个nextblock就是我们在订阅信号的时候创建的那个subscriber所保存的nextblock。
所以RACSignal的整体处理流程如下
- 创建信号的block会在订阅信号的时候调用 subscribe
- 订阅信号的block会在订阅者发布信息的时候调用 sendNext