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     */
posted @ 2018-12-15 18:32  jisa  阅读(145)  评论(0编辑  收藏  举报