源码解析

RACSignal,RACSubject,RACReplaySu

2018-04-24  本文已影响30人  哦呵呵y

系列文章
RACSignal,RACSubject,RACReplaySubject
RAC bind
RAC Merge flatten
RACMulticastConnection
RAC switchToLatest

一、 RACSignal信号类

    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [subscriber sendNext:nil];
        return nil;
    }];
    [signal subscribeNext:^(id  _Nullable x) {
    }];
...
// 订阅
    RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
    return [self subscribe:o];

//  RACDynamicSignal subscribe 内部实现
    RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
    subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];

    if (self.didSubscribe != NULL) {
        RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
            RACDisposable *innerDisposable = self.didSubscribe(subscriber);
            [disposable addDisposable:innerDisposable];
        }];  // 这里传入的block会立即调用。

        [disposable addDisposable:schedulingDisposable];
    }
    
    return disposable;
  1. 创建信号, 生成 RACDynamicSignal ,将传入的block 保存到信号的 didSubscribe Block中。
  2. 订阅信号,生成RACSubscriber并保存nextBlock, 然后调用信号类的subscribe方法设置订阅者,方法内部会调用信号对象中的 didSubscribe block。
  3. 发送信号, didSubscribe被调用后,可以获取到相应的订阅者,调用订阅者的sendNext方法会立马调用订阅信号时传入的nextBlock;
  4. 订阅时会触发创建时的block,而创建时的block内部会获取相应的订阅者,做完相应操作后,调用订阅者发送信号,触发订阅是创建的block;

二、RACSubject:信号提供者,自己可以充当信号,又能发送信号。

    RACSubject *subject = [RACSubject subject];
    [subject subscribeNext:^(id  _Nullable x) {
        
    }];
    [subject sendNext:@""];
...
// RACSubject subscribe 内部实现
    RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
    subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];

    NSMutableArray *subscribers = self.subscribers;
    @synchronized (subscribers) {
        [subscribers addObject:subscriber];
    }
    
    [disposable addDisposable:[RACDisposable disposableWithBlock:^{
        @synchronized (subscribers) {
            // Since newer subscribers are generally shorter-lived, search
            // starting from the end of the list.
            NSUInteger index = [subscribers indexOfObjectWithOptions:NSEnumerationReverse passingTest:^ BOOL (id<RACSubscriber> obj, NSUInteger index, BOOL *stop) {
                return obj == subscriber;
            }];

            if (index != NSNotFound) [subscribers removeObjectAtIndex:index];
        }
    }]];

    return disposable;
...
// 发送信号
    [self enumerateSubscribersUsingBlock:^(id<RACSubscriber> subscriber) {
        [subscriber sendNext:value];
    }];
  1. 创建信号,生成一个数组用来保存订阅者
  2. 订阅信号,生成订阅者,将订阅者保存到数组中
  3. 发送信号,遍历数组,将消息发送到每一个订阅者。

三、RACReplaySubject 继承自RACSubject

// RACReplaySubject subscribe 内部实现
    RACCompoundDisposable *compoundDisposable = [RACCompoundDisposable compoundDisposable];

    RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
        @synchronized (self) {
            for (id value in self.valuesReceived) {
                if (compoundDisposable.disposed) return;

                [subscriber sendNext:(value == RACTupleNil.tupleNil ? nil : value)];
            }

            if (compoundDisposable.disposed) return;

            if (self.hasCompleted) {
                [subscriber sendCompleted];
            } else if (self.hasError) {
                [subscriber sendError:self.error];
            } else {
                RACDisposable *subscriptionDisposable = [super subscribe:subscriber];
                [compoundDisposable addDisposable:subscriptionDisposable];
            }
        }
    }];

    [compoundDisposable addDisposable:schedulingDisposable];

    return compoundDisposable;
  1. 创建信号,在父类的基础上同时创建一个数组,用来保存历史消息
  2. 订阅信号,重写subscribe方法,先对当前订阅者发送所有历史消息,然后在将订阅者添加到数组中。
  3. 发送信号,同父类,遍历订阅者,发送消息。
上一篇下一篇

猜你喜欢

热点阅读