首页 > 科技 >

Pull-Driven 的数据流 RACSequence(6)

2018-08-21 03:58:15 网络整理 阅读:92 评论:0

-signal 方法的实现依赖于另一个实例方法 -signalWithScheduler:,它会在一个 RACScheduler 对象上发送序列中的所有元素:- (RACSignal *)signal { return [[self signalWithScheduler:[RACScheduler scheduler]] setNameWithFormat:@"[%@] -signal", self.name];} - (RACSignal *)signalWithScheduler:(RACScheduler *)scheduler { return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) { __block RACSequence *sequence = self; return [scheduler scheduleRecursiveBlock:^(void (^reschedule)(void)) { if (sequence.head == nil) { [subscriber sendCompleted]; return; } [subscriber sendNext:sequence.head]; sequence = sequence.tail; reschedule(); }]; }] setNameWithFormat:@"[%@] -signalWithScheduler: %@", self.name, scheduler];}

RACScheduler 并不是这篇文章准备介绍的内容,这里的代码其实相当于递归调用了 reschedule block,不断向 subscriber 发送 -sendNext:,直到 RACSequence 为空为止。 将 RACSignal 转换成 RACSequence

反向转换 RACSignal 的过程相比之下就稍微复杂一点了,我们需要连续调用两个方法,才能将它转换成 RACSequence。

通过一段代码来看转换过程是如何进行的:RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { [subscriber sendNext:@1]; [subscriber sendNext:@2]; [subscriber sendNext:@3]; [subscriber sendCompleted]; return nil;}];NSLog(@"%@", signal.toArray.rac_sequence);

运行上面的代码,会得到一个如下的 RACArraySequence 对象:<RACArraySequence: 0x608000024e80>{ name = , array = ( 1, 2, 3) }

在这里不想过多介绍其实现原理,我们只需要知道这里使用了 RACStream 提供的操作『收集』了信号发送过程中的发送的所有对象 @1、@2、@3 就可以了。 总结

相比于 RACSignal 来说,虽然 RACSequence 有很多的子类,但是它的用途和实现复杂度都少很多,这主要是因为它是 Pull-Driven 的,只有在使用时才会更新,所以我们一般只会使用 RACSequence 操作数据流,使用 map、filter、flattenMap 等方法快速操作数据。 References Reactive Cocoa · NSHipsterWhat is the difference between RACSequence and RACSignalReactiveCocoa Design Patterns

Github Repo:iOS-Source-Code-Analyze

Follow: Draveness · GitHub

Source: 『状态』驱动的世界:ReactiveCocoa​

相关文章