美文网首页
RACSequence

RACSequence

作者: boy丿log | 来源:发表于2019-04-03 16:22 被阅读0次

    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]);
    

    相关文章

      网友评论

          本文标题:RACSequence

          本文链接:https://www.haomeiwen.com/subject/iepzbqtx.html