美文网首页iOS开发iOS常用
iOS开发 「RAC」RAC信号组合的妙用

iOS开发 「RAC」RAC信号组合的妙用

作者: 俺不是大佬儿 | 来源:发表于2021-09-17 15:28 被阅读0次

    • concat:按一定顺序拼接信号,当多个信号发出的时候,有顺序的接收信号,依赖关系把一组信号串联起来,前面一个信号complete,后面一个信号才开始发挥作用

        //比如A请求依赖B请求,只有B请求完成之后才能执行A请求或操作
        RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"signalA"];
            return nil;
        }];
        
        RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"signalB"];
            //因为A依赖B,所以只需要在B里面声明发送完成
            [subscriber sendCompleted];
            return nil;
        }];
        
        //注意点:如果一个操作后面还被其他操作依赖,比如signalB,需要在其内部发送完数据后声明发送完成,[subscriber sendCompleted];
        RACSignal *contatSignal = [signalB concat:signalA];
        
        [contatSignal subscribeNext:^(id x) {
            NSLog(@"(concat)结果:%@",x);
            //输出结果
            //--TIME:13:59:40.659000+0800(concat)结果:signalB
            //--TIME:13:59:40.659000+0800(concat)结果:signalA
        }];
    

    • then:用于连接两个信号,当第一个信号完成,才会连接then返回的信号

    //A请求依赖B请求,只有B请求完成之后才能执行A的请求或操作,需要注意:这个方法最后只能拿到A的值,如果B不需要传值,只需要先进行某些操作的时候可以用then
        RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"signalA"];
            return nil;
        }];
        
        RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"signalB"];
            //注意:如果一个操作后面还被其他操作依赖,比如signalB,需要在其内部发送完数据后声明发送完成,[subscriber sendCompleted];
            [subscriber sendCompleted];
            return nil;
        }];
        
        RACSignal *thenSignal = [signalB then:^RACSignal *{
            return signalA;
        }];
        
        [thenSignal subscribeNext:^(id x) {
            NSLog(@"(then)结果:%@",x);
            //输出结果
            //--TIME:14:42:00.971000+0800 (then)结果:signalA
        }];
    

    \color{red}{then与concat区别: then监听不到第一个信号的值,共同点都是必须第一个信号完成,第二个信号才会激活}

    • merge:把多个信号合并为一个信号,任何一个信号有新值的时候就会调用

    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"signalA"];
            return nil;
        }];
        
        RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"signalB"];
            [subscriber sendCompleted];
            return nil;
        }];
        
        RACSignal *mergeSignal = [signalA merge:signalB];
        
        [mergeSignal subscribeNext:^(id x) {
            NSLog(@"(merge)结果:%@",x);
        }];
    

    • zipWith:把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元组,才会触发压缩流的next事件

    //信号压缩,这个方法其实和rac_liftSelector本质时一样的,把多个信号压缩成一个信号,只有被压缩的信号全部发出消息时才能调用
            RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
                [subscriber sendNext:@"signalA"];
                return nil;
            }];
            
            RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
                [subscriber sendNext:@"signalB"];
                return nil;
            }];
            
            //zipSignal是有顺序的
            RACSignal *zipSignal = [signalB zipWith:signalA];
            
            [zipSignal subscribeNext:^(id x) {
                //x是接受到的所有数据包装成的元组
                NSLog(@"(zipWith)结果:%@",x);
                //输出结果
                /*--TIME:14:53:55.966000+0800
                (zipWith)结果:<RACTwoTuple: 0x600003a2df90> (
                    signalB,
                    signalA
                )*/
            }];
    

    • combineLatest:将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的signal至少都有过一次sendNext,才会触发合并的信号

    • combineLatestWith:合并两个信号,当两个信号都有sendNext才会触发合并的信号

    • reduce:信号聚合,参数需要自己添加

    //多用于登录逻辑
        RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"signalA"];
            return nil;
        }];
        RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"signalB"];
            return nil;
        }];
        
        // 聚合
        // reduce:信号聚合,参数需要自己添加
        // 常见的用法,(先组合再聚合)。combineLatest:(id<NSFastEnumeration>)signals reduce:(id (^)())reduceBlock
        // reduce中的block简介:
        // reduceblcok中的参数,有多少信号组合,reduceblcok就有多少参数,每个参数就是之前信号发出的内容
        // reduceblcok的返回值:聚合信号之后的内容。
        RACSignal *combineSignal = [RACSignal combineLatest:@[signalA, signalB] reduce:^id(NSString *signalA, NSString *signalB){
            NSLog(@"%@----%@", signalA, signalB);
            //block:只要任意一个信号发出内容,就会调用
            //block参数个数:由信号决定
            //block参数类型:block的参数就是信号发出值
            //把两个信号中的值聚合成哪个值
            return @(signalA.length && signalB.length);
        }];
        
        [combineSignal subscribeNext:^(id x) {
            NSLog(@"(combineLatest)结果:%@",x);
            //输出结果
            //--TIME:14:53:55.966000+0800 (combineLatest)结果:1
        }];
        
        [[signalA combineLatestWith:signalB] subscribeNext:^(id  _Nullable x) {
                //x是接收两个信号合并后的数据包装成的元组(RACTuple)
            NSLog(@"(combineLatestWith)结果:%@",x);
            //输出结果
           /*--TIME:14:53:55.966000+0800
            (combineLatestWith)结果:<RACTwoTuple: 0x600003578620> (
                signalA,
                signalB
            )
            */
        }];
    

    欢迎大佬来指正纠错,共同学习

    相关文章

      网友评论

        本文标题:iOS开发 「RAC」RAC信号组合的妙用

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