Signal
RAC的核心是signal,RAC世界所有的消息都是通过信号的方式传递的。
- 创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@1];
[subscriber sendNext:@2];
[subscriber sendCompleted];
return nil;
}];
它的内部实现是创建一个RACDynamicSignal,同时将创建信号的block传递给RACDynamicSignal实例。
+ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
RACDynamicSignal *signal = [[self alloc] init];
signal->_didSubscribe = [didSubscribe copy];
return [signal setNameWithFormat:@"+createSignal:"];
}
- 订阅信号
信号创建之后如果不被订阅,block不会被执行
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"signal: %@", x);
}];
订阅的内部实现其实也是函数式编程思想,block传递
- 创建订阅者
RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
[self subscribe:o];
- 执行创建信号时的block
RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
RACDisposable *innerDisposable = self.didSubscribe(subscriber);
[disposable addDisposable:innerDisposable];
}];
Bind
信号的绑定是个相对复杂的操作,其内部是创建了一个新的信号
RACSignal *bindSignal = [signal bind:^RACSignalBindBlock _Nonnull{
return ^(NSNumber *value, BOOL *stop) {
value = @(value.integerValue * value.integerValue);
return [RACSignal return:value];
};
}];
除去RACDisposable处理过程,bind内部可简化成
- (RACSignal *)bind:(RACSignalBindBlock (^)(void))block {
return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
RACSignalBindBlock bindingBlock = block();
return [self subscribeNext:^(id x) {
BOOL stop = NO;
id signal = bindingBlock(x, &stop);
if (signal) {
[signal subscribeNext:^(id x) {
[subscriber sendNext:x];
} error:^(NSError *error) {
[subscriber sendError:error];
} completed:^{
[subscriber sendCompleted];
}];
}
if (signal == nil || stop) {
[subscriber sendCompleted];
}
} error:^(NSError *error) {
[subscriber sendError:error];
} completed:^{
[subscriber sendCompleted];
}];
}] setNameWithFormat:@"[%@] -bind:", self.name];
}
因为`RACReturnSignal订阅过程实现了sendNext
[RACScheduler.subscriptionScheduler schedule:^{
[subscriber sendNext:self.value];
[subscriber sendCompleted];
}];
当bindSignal被订阅时
[bindSignal subscribeNext:^(id _Nullable x) {
NSLog(@"bindSignal: %@", x);
}];
bindingBlock返回的returnSignal会被订阅,进而触发[subscriber sendNext:x]