美文网首页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