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]