本文是對ReactiveObjC原理簡介
一、流程分析
ReactiveObjC主要有三個關(guān)鍵類:
1、RACSignal 信號
RACSignal 是各種信號的基類,其中RACDynamicSignal是用的最多的動態(tài)信號
2、RACSubscriber 訂閱者
RACSubscriber是實現(xiàn)了RACSubscriber協(xié)議的訂閱者類,這個協(xié)議定義了4個必須實現(xiàn)的方法
@protocol RACSubscriber <NSObject>
@required
- (void)sendNext:(nullable id)value; //常見
- (void)sendError:(nullable NSError *)error; //常見
- (void)sendCompleted; //常見
- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)disposable;
@end
RACSubscriber主要保存了三個block,跟三個常見的協(xié)議方法一一對應
@property (nonatomic, copy) void (^next)(id value);
@property (nonatomic, copy) void (^error)(NSError *error);
@property (nonatomic, copy) void (^completed)(void);
3、RACDisposable 清潔工
RACDisposable 主要是對資源的釋放處理,其中使用RACDynamicSignal時,會創(chuàng)建一個RACCompoundDisposable管理清潔工對象。其內(nèi)部定義了兩個數(shù)組,一個是_inlineDisposables[2]固定長度2的A fast array,超出2個對象的長度由_disposables數(shù)組管理,_inlineDisposables數(shù)組速度快,兩個數(shù)組都是線程安全的。
4、簡單信號調(diào)用流程
結(jié)合以下代碼分析
//1、創(chuàng)建信號
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
//任何時候,都可以發(fā)送信號,可以異步
[subscriber sendNext:@"發(fā)送信號"];
[subscriber sendCompleted];
return nil;
}];
//2、訂閱信號
[signal subscribeNext:^(id _Nullable x) {
//收到信號時
NSLog(@"信號內(nèi)容:%@", x);
}];
調(diào)用流程如下:

注意:如果didSubscribe是異步執(zhí)行,則會先返回RACDisposable,然后執(zhí)行sendNext:
二、主要類分析
關(guān)于ReactiveObjC所有class的繼承關(guān)系

圖片來自(http://www.cnblogs.com/CoderEYLee/p/Object-C-0010.html)[http://www.cnblogs.com/CoderEYLee/p/Object-C-0010.html]
1、RACStream
RACStream是所有信號類的父類,也是一個抽象類。它定義了五個子類必須實現(xiàn)的方法:
+ (__kindof RACStream<ValueType> *)empty;
+ (__kindof RACStream<ValueType> *)return:(nullable ValueType)value;
- (__kindof RACStream *)bind:(RACStreamBindBlock (^)(void))block;
- (__kindof RACStream *)concat:(RACStream *)stream;
- (__kindof RACStream *)zipWith:(RACStream *)stream;
RACStream還定義了一個Operations的分類,分類中定義并實現(xiàn)了各種信號處理方法,都是使用以上5個方法,直接或間接實現(xiàn)的。子類繼承了RACStream之后,便可使用Operations分類中的所有方法。

2、RACSignal
RACSignal是個核心的信號類,繼承并實現(xiàn)了父類RACStream中的5個必要方法。
①empty實現(xiàn)
//返回一個空信號
return [[[self alloc] init] setNameWithFormat:@"+empty"];
②return實現(xiàn)
//將傳入對象保存,并返回信號
RACReturnSignal *signal = [[self alloc] init];
signal->_value = value;
③bind實現(xiàn)
//bind調(diào)用了一個傳入值,并且返回信號的block
typedef RACSignal * _Nullable (^RACSignalBindBlock)(ValueType _Nullable value, BOOL *stop);
//bind內(nèi)部調(diào)用RACSignalBindBlock之后,得到新的信號,然后給新的信號發(fā)送sendNext:,并在sendNext:內(nèi)部給原訂閱者發(fā)送sendNext:信號,傳入包裝后的值
//簡化后的bind
- (RACSignal *)bind:(RACSignalBindBlock (^)(void))block {
return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
//拿到實現(xiàn)的block
RACSignalBindBlock bindingBlock = block();
return [self subscribeNext:^(id x) {
BOOL stop = NO;
//調(diào)用數(shù)據(jù)處理的block
[bindingBlock(x, &stop) subscribeNext:^(id x) {
//并且把數(shù)據(jù)傳遞給原訂閱者
[subscriber sendNext:x];
}];
}];
}] setNameWithFormat:@"[%@] -bind:", self.name];
}
//調(diào)用
[[self.textField.rac_textSignal bind:^RACSignalBindBlock _Nonnull{ return ^RACSignal*(id value, BOOL *stop){
//bind實現(xiàn)的block內(nèi)部,拿到數(shù)據(jù),包裝成信號返回出去
return [RACSignal return:[NSString stringWithFormat:@"hello: %@",value]];
};
}] subscribeNext:^(id _Nullable x) {
NSLog(@"bind : %@",x); // hello: "x"
}];
④concat實現(xiàn)
//concat簡化后
- (RACSignal *)concat:(RACSignal *)signal {
return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
//先給信號本身發(fā)送sendNext:
return [self subscribeNext:^(id x) {
[subscriber sendNext:x];
} error:^(NSError *error) {
[subscriber sendError:error];
} completed:^{
//執(zhí)行完成之后,再給signal發(fā)送訂閱的消息
[signal subscribe:subscriber];
}];
}] setNameWithFormat:@"[%@] -concat: %@", self.name, signal];
}
//調(diào)用
RACSignal *signalA = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"signalA"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"signalB"];
[subscriber sendCompleted];
return nil;
}];
// 把signalA拼接到signalB后,signalA發(fā)送完成,signalB才會被激活 順序執(zhí)行
[[signalA concat:signalB] subscribeNext:^(id _Nullable x) {
//先拿到 signalA 的結(jié)果 , 再拿到 signalB 的結(jié)果 , 執(zhí)行兩次
NSLog(@"concat result = %@", x);
}];
⑤zipWith實現(xiàn)
//簡化后的zipWith
- (RACSignal *)zipWith:(RACSignal *)signal {
return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
NSMutableArray *selfValues = [NSMutableArray array];
NSMutableArray *otherValues = [NSMutableArray array];
__block NSInteger completedCount = 0;
void (^sendNext)(void) = ^{
@synchronized (selfValues) {
//當兩個信號都執(zhí)行完成時,將返回結(jié)果打包成元祖返回給原信號
//每次都是取數(shù)組的第1個元素,取完之后,數(shù)組清空,所以信號的數(shù)據(jù)都是一一對應的
RACTuple *tuple = RACTuplePack(selfValues[0], otherValues[0]);
[selfValues removeObjectAtIndex:0];
[otherValues removeObjectAtIndex:0];
[subscriber sendNext:tuple];
if (completedCount == 2) {
//當前信號完成
[subscriber sendCompleted];
}
}
};
//訂閱執(zhí)行第一個信號
[self subscribeNext:^(id x) {
[selfValues addObject:x ?: RACTupleNil.tupleNil];
completedCount++;
sendNext();
}];
//訂閱執(zhí)行第二個信號
[signal subscribeNext:^(id x) {
[otherValues addObject:x ?: RACTupleNil.tupleNil];
completedCount++;
sendNext();
}];
return [RACDisposable disposableWithBlock:^{}];
}] setNameWithFormat:@"[%@] -zipWith: %@", self.name, signal];
}
//調(diào)用
RACSignal *zipSignal = [zipSignalA zipWith:zipSignalB];
[zipSignal subscribeNext:^(id _Nullable x) {
// x 是一個元祖
RACTupleUnpack(NSNumber *a, NSNumber *b) = x;
}];
這里有一篇對ReactiveObjC 詳細的原理說明:
ReactiveObjC詳細原理