基于信號的響應(yīng)式編程框架搁宾。
RACSignal
信號基類RACSignal(繼承自RACStream),調(diào)用createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe方法會生成冷信號祥楣,并保存didSubscribe(此時并不會執(zhí)行didSubscribe)。
冷信號只有被訂閱時,才會變成熱信號茅诱。通過調(diào)用RACSignal的subscribeNext:方法金句,會生成一個RACSubscriber訂閱者檩赢, 之后調(diào)用subscribe: 方法(實際是調(diào)用RACDynamicSignal的subscribe:方法),在subscribe: 內(nèi)部會調(diào)用didSubscribe违寞。
常用的信號:RACDynamicSignal事件流信號贞瞒、RACErrorSignal錯誤信號、RACEmptySignal空信號(不觸發(fā)訂閱事件)趁曼。
RACSubscriber
訂閱者军浆,sendNext觸發(fā)subcribeNext,sendCompleted觸發(fā)subscribeCompleted挡闰,sendError觸發(fā)subscribeError瘾敢。sendNext后如果要移除信號,防止資源占用導(dǎo)致事件流堵塞尿这,需調(diào)用sendCompleted簇抵。
用流水線的角度來看,RACSignal相當于管線射众,RACSubscriber相當于工人碟摆,工人對傳過來的信號進行加工處理,觸發(fā)各種事件叨橱。
流程: createSianal,生成信號同時保存didSubscribe—>subscribeNext生成訂閱者典蜕,并調(diào)用—>subscribe—>didSubscribe—>合適時機調(diào)用sendNext等方法—>觸發(fā)subscribeNext等block執(zhí)行塊断盛。
RACSubject
繼承自RACSignal,熱信號愉舔。RACSubject不止有一個訂閱者钢猛,其內(nèi)部維護一個訂閱者數(shù)組。同時其能自發(fā)調(diào)用sendNext方法轩缤。
流程:sendNext—>subscibeNext
RACCommand
比較上層的工人命迈,內(nèi)部維護了多個RACSubject。
executionSignals 執(zhí)行內(nèi)部事務(wù)調(diào)用sendNext火的、sendError的響應(yīng)信號壶愤。
errors 執(zhí)行內(nèi)部事務(wù)調(diào)用sendError的響應(yīng)信號。
等等馏鹤。
以UIButton+RACCommandSupport的流程為例:
RACCommand的initWithSignalBlock生成一個rac_command,并保存signalBlock征椒,把rac_command傳給button。
button點擊—>rac_command.execute—>調(diào)用signalBlock生成信號—>signalBlock內(nèi)部的didSubscribe—>subscribe.sendNext湃累、sendError—>觸發(fā)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(@"執(zhí)行事件");
}];
}];
[button.rac_command.errors subscribeNext:^(NSError * _Nullable x) {
NSLog(@"錯誤發(fā)生");
}];
bind
map治力、flattenMap等方法都是基于bind剪芥,而bind的實現(xiàn)過程也能充分體現(xiàn)ReactiveObjC基于信號通信的思想。
信號1調(diào)用bind:bindBlcok?琴许,會返回信號2,信號2的didSubscribe?調(diào)用self的subscribeNext:error:completed方法(即信號1的subscribeNext:error:completed?)溉躲,在subscribeNext中用bindBlock生成信號3?榜田,并調(diào)用信號3的subscribeNext?,subscribeNext的執(zhí)行塊會調(diào)用信號2的subscriber.sendNext?, 從而觸發(fā)信號2的subscribeNext執(zhí)行塊?锻梳。
這樣每次信號1觸發(fā)時箭券,就會觸發(fā)信號2,從而實現(xiàn)了新信號綁定舊信號的功能疑枯。
流程:信號1的訂閱者subscriber1.sendNext—>信號1的subscribeNext block(?處)—>生成信號3—>信號3的subscribeNext block(?處)—>信號2的subscriber.sendNext(?處)—>信號2的subscribeNext block辩块。
從而實現(xiàn)了信號1觸發(fā)時,信號2的subscribeNext block能被執(zhí)行荆永。
常用的宏
RAC(id, property)
RACObserve(id, property)等