源码解析RAC+RxSwift

RAC Merge flatten

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

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

前面对bind、flattenMap已经有了一定的了解,而flatten内部其实是对flattenMap的封装,但是单看flatten,很难理解他的意义,需要结合Merge来看。

- (__kindof RACStream *)flatten {
    return [[self flattenMap:^(id value) {
        return value;
    }] setNameWithFormat:@"[%@] -flatten", self.name];
}
+ (RACSignal *)merge:(id<NSFastEnumeration>)signals {
    NSMutableArray *copiedSignals = [[NSMutableArray alloc] init];
    for (RACSignal *signal in signals) {
        [copiedSignals addObject:signal];
    }

    return [[[RACSignal
        createSignal:^ RACDisposable * (id<RACSubscriber> subscriber) {
            for (RACSignal *signal in copiedSignals) {
                [subscriber sendNext:signal];
            }

            [subscriber sendCompleted];
            return nil;
        }]
        flatten]
        setNameWithFormat:@"+merge: %@", copiedSignals];
}

通过之前的bind方法的分析,知道其实中间加了两层转发(bind生成一个新信号,接收到信号好,过滤生成一个新的信号,新的信号才转发到原信号),将原信号的消息转发到bind生成的信号中去

  1. bind中,我们默认使用了 RACReturnSignal包装了原信号发送的消息
  2. 而在merge中,我们创建了一个新的信号,然后调用flatten. 然后生成第二个信号返回出去
  3. flatten内部其实是bind,所以会立马订阅 merge创建的信号,这是会将merge合并的多个信号作为消息发送给订阅者。
  4. 这时bind内部,对原信号的订阅者就会收到消息,而消息正是用来合并的两个子信号。而子信号通过flatten中的方法直接返回自己,所以这里就不在是RACReturnSignal信号了,而是要合并的两个信号。
  5. 然后对着两个信号进行订阅。当收到消息是,在把消息发送给bind产生的信号中。

这里有几个注意点。
这个过程中产生了很多信号。1,要合并的两个信号、2,merge中先创建一个新的信号作为原信号来进行调用bind,用来将合并的两个信号作为消息发送到bind内部 、3,flatten 也就是bind生成了一个信号,而这个信号才是merge中返回的信号,才是用来订阅获取消息的信号。
普通bind中,原信号消息发送到bind内部,bind内部过滤后生成新的信号,新的信号将消息发送到bind生成的信号中(RACReturnSignal类型相当于直接转发了信号)
merge/flatten中,将两个信号合并生成一个新的信号作为原信号,此信号进行bind,并且将要合并的两个信号发送到bind内部,因为flatten中的实现是直接返回信号本身,所以这里并没有生成新的信号,而且获取到了外部要合并的两个信号,并且订阅了两个信号,将消息转发到bind生成的信号中。

普通bind流程 merge/flatten
上一篇下一篇

猜你喜欢

热点阅读