ReactiveCocoa 源码阅读记录。
1:RACSingle 需要订阅信号
1 RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { 2 [subscriber sendNext:@"1"]; 3 [subscriber sendCompleted]; 4 return nil; 5 }]; 6 7 [signal subscribeNext:^(id x) { 8 9 } error:^(NSError * _Nullable error) { 10 11 } completed:^{ 12 13 }]; 14 /************* 对应的源码 **************/ 15 // 生成RACDynamicSignal。即生成RACSignal的子类 16 + (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe { 17 return [RACDynamicSignal createSignal:didSubscribe]; 18 } 19 20 // 在子类中保存 didSubscribe block, 每一次订阅都会执行 21 + (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe { 22 RACDynamicSignal *signal = [[self alloc] init]; 23 signal->_didSubscribe = [didSubscribe copy]; 24 return [signal setNameWithFormat:@"+createSignal:"]; 25 } 26 27 /// 在订阅时执行保存在RACDynamicSignal中的didSubscribe block 28 - (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber { 29 NSCParameterAssert(subscriber != nil); 30 31 RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable]; 32 subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable]; 33 34 if (self.didSubscribe != NULL) { 35 RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{ 36 RACDisposable *innerDisposable = self.didSubscribe(subscriber); 37 [disposable addDisposable:innerDisposable]; 38 }]; 39 40 [disposable addDisposable:schedulingDisposable]; 41 } 42 43 return disposable; 44 } 45 46 // 生成订阅者。并调用RACDynamicSignal中的订阅方法,执行didSubscribe block 47 - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock { 48 NSCParameterAssert(nextBlock != NULL); 49 50 RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL]; 51 return [self subscribe:o]; 52 } 53 54 // 生成的订阅者中保存 nextBlock, errorBlock, completedBlock. 55 + (instancetype)subscriberWithNext:(void (^)(id x))next error:(void (^)(NSError *error))error completed:(void (^)(void))completed { 56 RACSubscriber *subscriber = [[self alloc] init]; 57 58 subscriber->_next = [next copy]; 59 subscriber->_error = [error copy]; 60 subscriber->_completed = [completed copy]; 61 62 return subscriber; 63 } 64 65 // 当订阅者收到sendNext方法时,就会执行nextBlock 66 - (void)sendNext:(id)value { 67 @synchronized (self) { 68 void (^nextBlock)(id) = [self.next copy]; 69 if (nextBlock == nil) return; 70 71 nextBlock(value); 72 } 73 }
2 RACSubject 既能订阅信号又能发送信号。 必须先订阅在发送。不然由于在sendNext时还没有订阅者会无法触发。
1 /// 事例 2 RACSubject *sub = [[RACSubject alloc] init]; 3 [sub subscribeNext:^(id _Nullable x) { 4 NSLog(@"%@", a); 5 }]; 6 7 [sub sendNext:@"a"];
1 //调用时和RACSignal有区别的方法 2 // 使用 subscribers 保存 订阅者。(RACDynamicSignal 还要执行didSubscrbe Block) 3 - (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber { 4 NSCParameterAssert(subscriber != nil); 5 6 RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable]; 7 subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable]; 8 9 NSMutableArray *subscribers = self.subscribers; 10 @synchronized (subscribers) { 11 [subscribers addObject:subscriber]; 12 } 13 14 [disposable addDisposable:[RACDisposable disposableWithBlock:^{ 15 @synchronized (subscribers) { 16 // Since newer subscribers are generally shorter-lived, search 17 // starting from the end of the list. 18 NSUInteger index = [subscribers indexOfObjectWithOptions:NSEnumerationReverse passingTest:^ BOOL (id<RACSubscriber> obj, NSUInteger index, BOOL *stop) { 19 return obj == subscriber; 20 }]; 21 22 if (index != NSNotFound) [subscribers removeObjectAtIndex:index]; 23 } 24 }]]; 25 26 return disposable; 27 } 28 29 // 找到需要的订阅者 30 - (void)enumerateSubscribersUsingBlock:(void (^)(id<RACSubscriber> subscriber))block { 31 NSArray *subscribers; 32 @synchronized (self.subscribers) { 33 subscribers = [self.subscribers copy]; 34 } 35 36 for (id<RACSubscriber> subscriber in subscribers) { 37 block(subscriber); 38 } 39 } 40 41 // 这行nextBlock。 42 - (void)sendNext:(id)value { 43 [self enumerateSubscribersUsingBlock:^(id<RACSubscriber> subscriber) { 44 [subscriber sendNext:value]; 45 }]; 46 }
3 bind bind是RAC中map,merge, flatten, flattenMap的基础
flattenMap 实际上就是调用bind。 经过flattenMap映射后,subscribe的是block(value)即block里面的信号
map 调用的flattenMap 经过Map映射后 subscribe的是[self return:block(value)]的信号假定为wrapSignal.而不是block(value)的信号假定为子信号。
flatten 调用的是flattenMap,subscribe的子信号。调用flatten订阅到的值必须是一个Signal。
1 RACSignal *returnSig = [RACSignal return:@"8"]; 2 RACSignal *bindSig = [returnSig bind:^RACSignalBindBlock { 3 return ^RACSignal * (id value, BOOL *bl) { 4 return [RACSignal return:value]; 5 }; 6 }]; 7 8 [bindSig subscribeNext:^(id _Nullable x) { 9 NSLog(@"%@", x); 10 }]; 11 /* 12 * -bind: should: 13 * 订阅原始信号,并将订阅到的原始信号值,赋值给binding block。如果binding block返回了新的信号。订阅它, 之后用生成的中转信号的订阅者,执行返回的信号的sendNext方法和 sendComplete方法 14 * 1. Subscribe to the original signal of values. 15 * 2. Any time the original signal sends a value, transform it using the binding block. 16 * 3. If the binding block returns a signal, subscribe to it, and pass all of its values through to the subscriber as they're received. 17 * 4. If the binding block asks the bind to terminate, complete the _original_ signal. 18 * 5. When _all_ signals complete, send completed to the subscriber. 19 * 20 * If any signal sends an error at any point, send that to the subscriber. 21 */ 22 23 /* 24 - (RACSignal *)bind:(RACSignalBindBlock (^)(void))block { 25 NSCParameterAssert(block != NULL); 26 27 return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) { 28 RACSignalBindBlock bindingBlock = block(); 29 30 __block volatile int32_t signalCount = 1; // indicates self 31 32 RACCompoundDisposable *compoundDisposable = [RACCompoundDisposable compoundDisposable]; 33 34 void (^completeSignal)(RACDisposable *) = ^(RACDisposable *finishedDisposable) { 35 if (OSAtomicDecrement32Barrier(&signalCount) == 0) { 36 [subscriber sendCompleted]; 37 [compoundDisposable dispose]; 38 } else { 39 [compoundDisposable removeDisposable:finishedDisposable]; 40 } 41 }; 42 // signal 是bindingBlock返回的信号。订阅这个信号。由于在Block中有这个信号的sendNext方法故会直接执行他。之后接收到的值发送出去。 43 void (^addSignal)(RACSignal *) = ^(RACSignal *signal) { 44 OSAtomicIncrement32Barrier(&signalCount); 45 46 RACSerialDisposable *selfDisposable = [[RACSerialDisposable alloc] init]; 47 [compoundDisposable addDisposable:selfDisposable]; 48 49 RACDisposable *disposable = [signal subscribeNext:^(id x) { 50 [subscriber sendNext:x]; 51 } error:^(NSError *error) { 52 [compoundDisposable dispose]; 53 [subscriber sendError:error]; 54 } completed:^{ 55 @autoreleasepool { 56 completeSignal(selfDisposable); 57 } 58 }]; 59 60 selfDisposable.disposable = disposable; 61 }; 62 63 @autoreleasepool { 64 RACSerialDisposable *selfDisposable = [[RACSerialDisposable alloc] init]; 65 [compoundDisposable addDisposable:selfDisposable]; 66 // 订阅初始的信号(上面的returnSig), 执行bindingBLock, 67 RACDisposable *bindingDisposable = [self subscribeNext:^(id x) { 68 // Manually check disposal to handle synchronous errors. 69 if (compoundDisposable.disposed) return; 70 71 BOOL stop = NO; 72 id signal = bindingBlock(x, &stop); 73 74 @autoreleasepool { 75 if (signal != nil) addSignal(signal); 76 if (signal == nil || stop) { 77 [selfDisposable dispose]; 78 completeSignal(selfDisposable); 79 } 80 } 81 } error:^(NSError *error) { 82 [compoundDisposable dispose]; 83 [subscriber sendError:error]; 84 } completed:^{ 85 @autoreleasepool { 86 completeSignal(selfDisposable); 87 } 88 }]; 89 90 selfDisposable.disposable = bindingDisposable; 91 } 92 93 return compoundDisposable; 94 }] setNameWithFormat:@"[%@] -bind:", self.name]; 95 } 96 97 */