美文网首页
RAC - 映射(Map & flattenMap)

RAC - 映射(Map & flattenMap)

作者: 下班不写程序 | 来源:发表于2020-10-21 13:31 被阅读0次

    文章系列
    《ReactiveCocoa 概述》
    《RACSignal》
    《RACDisposable》
    《RACSubject、RACReplaySubject(内附冷信号和热信号的区别)》
    《集合RACTuple、RACSequence》
    《RAC 中的通知、代理、KVO, 基本事件、方法的监听》
    《rac_liftSelector》
    《RACMulticastConnection》
    《RACCommand》
    《RAC - 核心方法bind》
    《RAC - 定时器》
    《RACScheduler》
    《RAC - 点击获取验证码 demo》
    《RAC - 映射(Map & flattenMap)》
    《RAC信号操作解释合集》
    《RAC - 信号的生命周期》

    flattenMapMap 都用于把源信号内容映射成新的内容.

    flattenMap

    作用: 用于信号中信号,把源信号的内容映射成一个新的信号,信号可以是任意类型

    flattenMap使用步骤:

    • 传入一个block, block 类型是返回值RACStream,参数value.
    • 参数value 就是源信号的内容, 拿到源信号的内容做处理.
    • 包装成RACReturnSignal 信号,返回出去.
    - (void)flatteMapTest {
        
        // 创建信号
        RACSubject *subject = [RACSubject subject];
        
        // 绑定信号
        RACSignal *bindSignal = [subject flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value) {
            
            // value: 源信号发送的内容
            value = [NSString stringWithFormat:@"flattenMap 后的信号:%@", value];
            
            // 返回的信号:用来包装成修改内容值
            return [RACReturnSignal return:value];
        }];
                                 
        // flattenMap中返回的是什么信号,订阅的就是什么信号
        // 订阅信号
        [bindSignal subscribeNext:^(id x) {
            
            NSLog(@"%@", x);
        }];
        
        // 发送数据
        [subject sendNext:@1];
    }
    
    打印结果

    flattenMap底层实现:

    1. flattenMap内部调用bind方法实现的, flattenMapblock的返回值,会作为bindbindBlock的返回值.
    2. 当订阅绑定信号,就会生成bindBlock.
    3. 当源信号发送内容,就会调用bindBlock(value, *stop).
    4. 调用bindBlock, 内部就会调用flattenMapblock, flattenMapblock作用:就是把处理好的数据包装成信号.
    5. 返回的信号最终会作为bindBlock中的返回信号,当做bindBlock的返回信号.
    6. 订阅bindBlock的返回信号,就会拿到绑定信号的订阅者,把处理完成的信号内容发送出来.
    - (__kindof RACStream *)flattenMap:(__kindof RACStream * (^)(id value))block {
        Class class = self.class;
    
        return [[self bind:^{
            return ^(id value, BOOL *stop) {
                id stream = block(value) ?: [class empty];
                NSCAssert([stream isKindOfClass:RACStream.class], @"Value returned from -flattenMap: is not a stream: %@", stream);
    
                return stream;
            };
        }] setNameWithFormat:@"[%@] -flattenMap:", self.name];
    }
    

    Map

    作用: 把源信号的值映射成一个新的值

    Map使用步骤:

    • 传入一个block, 类型是返回对象, 参数是value.
    • value 就是源信号的内容,直接拿到源信号的内容做处理.
    • 把处理好的内容,直接返回就好了,不用包装成信号,返回的值,就是映射的值.
    - (void)mapTest {
        
        RACSubject *subject = [RACSubject subject];
        
        RACSignal *Signal = [subject map:^id _Nullable(NSNumber *value) {
            
            value = @(value.integerValue + 1);
            return value;
        }];
        
        [Signal subscribeNext:^(id  _Nullable x) {
           
            NSLog(@"%@", x);
        }];
        
        [subject sendNext:@1];
    }
    

    信号subject发送的是1, 但是Map内部的操作是将所有发送的值做加一操作, 多以打印结果为2

    打印结果

    Map底层实现:

    1. Map底层其实是调用flatternMap,Mapblock中的返回的值会作为flatternMapblock中的值.
    2. 当订阅绑定信号, 就会生成bindBlock.
    3. 当源信号发送内容,就会调用bindBlock(value, *stop).
      4.调用bindBlock,内部就会调用flattenMapblock.
    4. flattenMapblock内部会调用Map中的block,把Map中的block返回的内容包装成返回的信号.
    5. 返回的信号最终会作为bindBlock中的返回信号,当做bindBlock的返回信号.
    6. 订阅bindBlock的返回信号,就会拿到绑定信号的订阅者,把处理完成的信号内容发送出来.

    FlatternMap和Map的区别

    1. FlatternMap 中的Block 返回信号.
    2. Map 中的Block 返回对象.
    3. 开发中,如果信号发出的值不是信号,映射一般使用Map.
    4. 开发中,如果信号发出的值是信号,映射一般使用FlatternMap.
    

    FlatternMap直接处理信号中的信号示例:

    - (void)flattenMapTest2{
    
        RACSubject *signalOfsignals = [RACSubject subject];
        
        RACSubject *signal1 = [RACSubject subject];
        RACSubject *signal2 = [RACSubject subject];
    
        [[signalOfsignals flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value) {
            
            // 当signalOfsignals的signals发出信号才会调用
            return value;
        }] subscribeNext:^(id  _Nullable x) {
            
            // 只有signalOfsignals 的signal 发出信号才会调用,
            // 也就是flattenMap返回的信号(上面的value)发出内容,才会调用。
            NSLog(@"x=%@",x);
        }];
          
        // 信号的信号发送信号
        [signalOfsignals sendNext:signal1];
        [signalOfsignals sendNext:signal2];
    
        // 信号发送内容
        [signal1 sendNext:@1];
        [signal1 sendNext:@2];
        [signal2 sendNext:@3];
    }
    
    打印结果
    注:

    高阶信号使用switchToLatest , 关注的是高阶信号中的最后一个信号.
    高阶信号使用flattenMap, 是把整个高阶信号扁平化, 得到一个低阶信号.

    .End

    相关文章

      网友评论

          本文标题:RAC - 映射(Map & flattenMap)

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