1. 程式人生 > >ReactiveCocoa 原始碼閱讀記錄。

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 }