在前面提到了RAC的订阅原理,虽然中间忽略了一些其它东西(比如说RACSchedule,RACDisposable),但任何一个RACSignal的订阅事件的value的流向都是如此。既然是一步步的流,那我们在使用过程中,必然会出现想要改变这个流,或者对这个流进行一些包装。简单的说,从一个RACSignal在经过中间某一步的操作,已经变成另外一个RACSignal;
1. RACSignal bind概况
RACSignal的bind的主要过程如下:
- 创建一个RACSignal的数组,把初始signal添加进去,如果该数组为空,发送complete;数组中任意的signal出现error,都会发送error;数组中任意的signal出现complete,都会让该数组删除该signal。
- 订阅初始Signal,获得初始Signal中所有的value,error,complete信息。
- 接受到value之后,通过RACStreamBindBlock这个block执行获得一个新的Signal,将这个Signal添加到数组中,并订阅这个signal。这个RACStreamBindBlock执行中会带一个BOOL值,如果BOOL值变成YES,初始Signal的订阅就结束了。
2. RACSignal bind源码分析
(1)如下代码段,首先是创建一个RACSignal的数组signals,初始只有
self也就是最初的signal。
NSMutableArray
*signals = [
NSMutableArray
arrayWithObject
:
self
];
(2)如下代码段,在往这个数组添加一个RACSignal时,这个signal都会被订阅:value值都会被传递的send出去,error会终止整体的订阅,complete会将这个signal从数组signals中删除。
void
(^addSignal)(
RACSignal
*) = ^(
RACSignal
*signal) {
@synchronized (signals) {
[signals addObject :signal];
}
RACSerialDisposable *selfDisposable = [[ RACSerialDisposable alloc ] init ];
[compoundDisposable addDisposable :selfDisposable];
RACDisposable *disposable = [signal subscribeNext:^(id x) {
[subscriber sendNext :x];
} error :^( NSError *error) {
[compoundDisposable dispose ];
[subscriber sendError :error];
} completed :^{
@autoreleasepool {
completeSignal(signal, selfDisposable);
}
}];
selfDisposable. disposable = disposable;
@synchronized (signals) {
[signals addObject :signal];
}
RACSerialDisposable *selfDisposable = [[ RACSerialDisposable alloc ] init ];
[compoundDisposable addDisposable :selfDisposable];
RACDisposable *disposable = [signal subscribeNext:^(id x) {
[subscriber sendNext :x];
} error :^( NSError *error) {
[compoundDisposable dispose ];
[subscriber sendError :error];
} completed :^{
@autoreleasepool {
completeSignal(signal, selfDisposable);
}
}];
selfDisposable. disposable = disposable;
};
(3)如下代码段,在这个数组中删除一个RACSignal时,判断数组中是否为空,为空的话,就sendCompleted
void
(^completeSignal)(
RACSignal
*,
RACDisposable
*) = ^(
RACSignal
*signal,
RACDisposable
*finishedDisposable) {