RACSequence
RACSequence是继承于RACStream,用来方便实现数据处理的,他一共有9个子类,分别是:
- RACArraySequence,用来处理数组
- RACEagerSequence,继承于RACArraySequence,用来处理积极运算。
- RACDynamicSequence,用来初始化的类
- RACEmptySequence,空类
- RACIndexSetSequence,用来处理index
- RACStringSequence,用来处理字符串
- RACSignalSequence,用来处理信号
- RACTupleSequence,用来处理元组
- RACUnarySequence,用来处理一元数据
接下来从父类RACSequence开始分析:
自身的方法
@interface RACSequence<__covariant ValueType> : RACStream <NSCoding, NSCopying, NSFastEnumeration>
//第一个元素
@property (nonatomic, strong, readonly, nullable) ValueType head;
//后面的元素
@property (nonatomic, strong, readonly, nullable) RACSequence<ValueType> *tail;
//总数组
@property (nonatomic, copy, readonly) NSArray<ValueType> *array;
//快速枚举
@property (nonatomic, copy, readonly) NSEnumerator<ValueType> *objectEnumerator;
//积极运算
@property (nonatomic, copy, readonly) RACSequence<ValueType> *eagerSequence;
//惰性运算
@property (nonatomic, copy, readonly) RACSequence<ValueType> *lazySequence;
//信号
- (RACSignal<ValueType> *)signal;
//
- (RACSignal<ValueType> *)signalWithScheduler:(RACScheduler *)scheduler;
//
- (id)foldLeftWithStart:(nullable id)start reduce:(id _Nullable (^)(id _Nullable accumulator, ValueType _Nullable value))reduce;
//
- (id)foldRightWithStart:(nullable id)start reduce:(id _Nullable (^)(id _Nullable first, RACSequence *rest))reduce;
//
- (BOOL)any:(BOOL (^)(ValueType _Nullable value))block;
//
- (BOOL)all:(BOOL (^)(ValueType _Nullable value))block;
//
- (nullable ValueType)objectPassingTest:(BOOL (^)(ValueType _Nullable value))block;
//
+ (RACSequence<ValueType> *)sequenceWithHeadBlock:(ValueType _Nullable (^)(void))headBlock tailBlock:(nullable RACSequence<ValueType> *(^)(void))tailBlock;
接下来我们看看这些属性和方法都做了什么。
一、初始化--sequenceWithHeadBlock: tailBlock:
+ (RACSequence *)sequenceWithHeadBlock:(id (^)(void))headBlock tailBlock:(RACSequence<id> *(^)(void))tailBlock {
return [[RACDynamicSequence sequenceWithHeadBlock:headBlock tailBlock:tailBlock] setNameWithFormat:@"+sequenceWithHeadBlock:tailBlock:"];
}
用子类完成初始化,传入一个block
二、- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(__unsafe_unretained id *)stackbuf count:(NSUInteger)len
实现NSFastEnumration协议,使自定义对象支持for循环,在此方法视线中,将每一个sequence的head去了出来放到缓冲区中,for循环实际是for循环了所有的head
三、- (NSArray *)array
返回的是一个包含所有head的数组
四、- (NSEnumerator *)objectEnumerator
@interface RACSequenceEnumerator : NSEnumerator
// The sequence the enumerator is enumerating.
//
// This will change as the enumerator is exhausted. This property should only be
// accessed while synchronized on self.
@property (nonatomic, strong) RACSequence *sequence;
@end
@implementation RACSequenceEnumerator
- (id)nextObject {
id object = nil;
@synchronized (self) {
object = self.sequence.head;
self.sequence = self.sequence.tail;
}
return object;
}
@end
可以看到,这是一个自定义快速枚举,nextObject返回的是当前sequence的tail
- (NSEnumerator *)objectEnumerator {
RACSequenceEnumerator *enumerator = [[RACSequenceEnumerator alloc] init];
enumerator.sequence = self;
return enumerator;
}
在初始化的时候设置sequence为当前值
五、- (RACSignal *)signalWithScheduler:(RACScheduler *)scheduler
- (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];
}
生成一个signal对象,这个对象可以遍历返回head,遍历完成后发送sendCompleted信号。
六、- (id)foldLeftWithStart:(id)start reduce:(id (^)(id, id))reduce
- (id)foldLeftWithStart:(id)start reduce:(id (^)(id, id))reduce {
NSCParameterAssert(reduce != NULL);
if (self.head == nil) return start;
for (id value in self) {
start = reduce(start, value);
}
return start;
}
从左开始根据reduceblock处理的结果,start累加左边,最后返回start
七、- (id)foldRightWithStart:(id)start reduce:(id (^)(id, RACSequence *))reduce
- (id)foldRightWithStart:(id)start reduce:(id (^)(id, RACSequence *))reduce {
NSCParameterAssert(reduce != NULL);
if (self.head == nil) return start;
RACSequence *rest = [RACSequence sequenceWithHeadBlock:^{
if (self.tail) {
return [self.tail foldRightWithStart:start reduce:reduce];
} else {
return start;
}
} tailBlock:nil];
return reduce(self.head, rest);
}
同上,从右边累加
八、- (BOOL)any:(BOOL (^)(id))block
是否包含数据
- (BOOL)any:(BOOL (^)(id))block {
NSCParameterAssert(block != NULL);
return [self objectPassingTest:block] != nil;
}
四、- (id)objectPassingTest:(BOOL (^)(id))block
返回过滤的那个head
- (id)objectPassingTest:(BOOL (^)(id))block {
NSCParameterAssert(block != NULL);
return [self filter:block].head;
}
在RACSignal章节,我们知道父类RACStream的filter方法是用来过滤信息的。
五、- (BOOL)all:(BOOL (^)(id))block
- (BOOL)all:(BOOL (^)(id))block {
NSCParameterAssert(block != NULL);
NSNumber *result = [self foldLeftWithStart:@YES reduce:^(NSNumber *accumulator, id value) {
return @(accumulator.boolValue && block(value));
}];
return result.boolValue;
}
判断所有值是否满足要求
六、- (RACSequence *)lazySequence
返回自身
七、- (RACSequence *)eagerSequence
- (RACSequence *)eagerSequence {
return [RACEagerSequence sequenceWithArray:self.array offset:0];
}
返回一个积极的数组
父类的方法
+ (RACSequence<ValueType> *)return:(nullable ValueType)value;
+ (RACSequence<ValueType> *)empty;
typedef RACSequence * _Nullable (^RACSequenceBindBlock)(ValueType _Nullable value, BOOL *stop);
- (RACSequence *)bind:(RACSequenceBindBlock (^)(void))block;
- (RACSequence *)concat:(RACSequence *)sequence;
- (RACSequence<RACTuple *> *)zipWith:(RACSequence *)sequence
一、+ (RACSequence *)empty
+ (RACSequence *)empty {
return RACEmptySequence.empty;
}
返回一个空的对象
二、+ (RACSequence *)return:(id)value
返回RACUnarySequence,head值设为value
三、- (RACSequence *)bind:(RACSequenceBindBlock (^)(void))block
通过block回调一个RACSequence,并执行(五)方法
四、- (RACSequence *)bind:(RACSequenceBindBlock)bindBlock passingThroughValuesFromSequence:(RACSequence *)passthroughSequence
- (RACSequence *)bind:(RACSequenceBindBlock)bindBlock passingThroughValuesFromSequence:(RACSequence *)passthroughSequence {
__block RACSequence *valuesSeq = self;
__block RACSequence *current = passthroughSequence;//依赖的序列
__block BOOL stop = NO;//状态记录
RACSequence *sequence = [RACDynamicSequence sequenceWithLazyDependency:^ id {
while (current.head == nil) {//如果currnet的head有值,跳出循环
if (stop) return nil;//如果要停止,则返回nil
id value = valuesSeq.head;
if (value == nil) {//如果head为nil跳出循环
stop = YES;
return nil;
}
current = (id)bindBlock(value, &stop);
if (current == nil) {////如果head为nil跳出循环
stop = YES;
return nil;
}
valuesSeq = valuesSeq.tail;
}
NSCAssert([current isKindOfClass:RACSequence.class], @"-bind: block returned an object that is not a sequence: %@", current);
return nil;
} headBlock:^(id _) {
return current.head;
} tailBlock:^ id (id _) {
if (stop) return nil;
return [valuesSeq bind:bindBlock passingThroughValuesFromSequence:current.tail];
}];
sequence.name = self.name;
return sequence;
}
这个函数用递归的方式,创建了一个sequence.通过传入的block和stop来确定转换值和是否停止,block需要返回一个RACSequence对象。
流程图 递归创建示例用法
RACSequence *sequence = [RACDynamicSequence sequenceWithHeadBlock:^id _Nullable{
return @"1";
} tailBlock:^RACSequence * _Nonnull{
return @[@"2",@"3",@"4"].rac_sequence;
}];
NSLog(@"%@ %@",sequence.head,sequence.tail);
sequence = [sequence bind:^RACSequenceBindBlock _Nonnull{
return ^ (NSString *value,BOOL *stop){
return [RACSequence return:@([value integerValue] + 1)];
};
}];
NSLog(@"%@ %@",sequence.head,[sequence.tail tail]);
网友评论