基于信号的响应式编程框架。
RACSignal
信号基类RACSignal(继承自RACStream),调用createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe方法会生成冷信号,并保存didSubscribe(此时并不会执行didSubscribe)。
冷信号只有被订阅时,才会变成热信号。通过调用RACSignal的subscribeNext:方法,会生成一个RACSubscriber订阅者, 之后调用subscribe: 方法(实际是调用RACDynamicSignal的subscribe:方法),在subscribe: 内部会调用didSubscribe。
常用的信号:RACDynamicSignal事件流信号、RACErrorSignal错误信号、RACEmptySignal空信号(不触发订阅事件)。
RACSubscriber
订阅者,sendNext触发subcribeNext,sendCompleted触发subscribeCompleted,sendError触发subscribeError。sendNext后如果要移除信号,防止资源占用导致事件流堵塞,需调用sendCompleted。
用流水线的角度来看,RACSignal相当于管线,RACSubscriber相当于工人,工人对传过来的信号进行加工处理,触发各种事件。
流程: createSianal,生成信号同时保存didSubscribe—>subscribeNext生成订阅者,并调用—>subscribe—>didSubscribe—>合适时机调用sendNext等方法—>触发subscribeNext等block执行块。
RACSubject
继承自RACSignal,热信号。RACSubject不止有一个订阅者,其内部维护一个订阅者数组。同时其能自发调用sendNext方法。
流程:sendNext—>subscibeNext
RACCommand
比较上层的工人,内部维护了多个RACSubject。
executionSignals 执行内部事务调用sendNext、sendError的响应信号。
errors 执行内部事务调用sendError的响应信号。
等等。
以UIButton+RACCommandSupport的流程为例:
RACCommand的initWithSignalBlock生成一个rac_command,并保存signalBlock,把rac_command传给button。
button点击—>rac_command.execute—>调用signalBlock生成信号—>signalBlock内部的didSubscribe—>subscribe.sendNext、sendError—>触发executionSignals.subscribeNext、errors.subscribeNext。
static NSInteger iii = 0;
button.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
NSLog(@"button pressed");
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
if (iii % 2== 0) {
[subscriber sendNext:input];
[subscriber sendCompleted];
} else {
[subscriber sendError:nil];
}
iii++;
return nil;
}];
}];
[button.rac_command.executionSignals subscribeNext:^(RACSignal<id> * _Nullable x) {
RACSignal *s = (RACSignal *)x;
[s subscribeNext:^(id _Nullable x) {
NSLog(@"执行事件");
}];
}];
[button.rac_command.errors subscribeNext:^(NSError * _Nullable x) {
NSLog(@"错误发生");
}];
bind
map、flattenMap等方法都是基于bind,而bind的实现过程也能充分体现ReactiveObjC基于信号通信的思想。
信号1调用bind:bindBlcok❶,会返回信号2,信号2的didSubscribe❷调用self的subscribeNext:error:completed方法(即信号1的subscribeNext:error:completed❸),在subscribeNext中用bindBlock生成信号3❹,并调用信号3的subscribeNext❺,subscribeNext的执行块会调用信号2的subscriber.sendNext❻, 从而触发信号2的subscribeNext执行块❼。
这样每次信号1触发时,就会触发信号2,从而实现了新信号绑定旧信号的功能。
流程:信号1的订阅者subscriber1.sendNext—>信号1的subscribeNext block(❸处)—>生成信号3—>信号3的subscribeNext block(❺处)—>信号2的subscriber.sendNext(❻处)—>信号2的subscribeNext block。
从而实现了信号1触发时,信号2的subscribeNext block能被执行。
常用的宏
RAC(id, property)
RACObserve(id, property)等