美文网首页
ReactiveCocoa(3)高级用法

ReactiveCocoa(3)高级用法

作者: 子疯zp | 来源:发表于2017-05-23 15:27 被阅读228次

    这篇主要运用RACSubject

    先复习下第一篇中说到的RACSubject,话不多说,上来就是RAC三部曲

    //创建信号
    RACSubject *subject = [RACSubject subject];
    //订阅信号
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    //发送信号
    [subject sendNext:@"en"];
    
    

    OK,切入正题

    一、flattenMap, Map 映射

    这两个方法就是将我们的信号源的内容应设成一个新的信号。

    之前我们就有提到过,我们为什么要绑定信号?就是要在信号发过来之前对信号进行处理,那么在这里我们要对他进行的处理就是映射。

    所以现在我们要对他返回一个信号,之前我们提过要返回的话我们要导入一个头文件。#import “RACReturnSignal.h"

    接下来我们来使用这个return
    return [RACReturnSignal return:(id)];

    完整代码如下

    //创建信号
    RACSubject *subject = [RACSubject subject];
    
    //flattenMap, map 映射
    //返回一个信号源
    [[subject flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value) {
        
        NSString *valueStr = [NSString stringWithFormat:@"被处理过的 %@ 数据",value];
        return [RACReplaySubject return:valueStr];
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //发送信号
    [subject sendNext:@"123"];
    

    但是有没有觉得有点麻烦,有点绕啊!好我们有请Map代替flattenMap!!

    [[subject map:^id _Nullable(id  _Nullable value) {
        NSString *valueStr = [NSString stringWithFormat:@"被处理过的 %@ 数据",value];
        return valueStr;
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    

    这时候有没有觉得简单了好多!

    那么问题来了!既然map 这么简单,为什么我们还要有flattenMap 呢?

    他当然有他的特殊的地方了,通常 flattenMap 用在处理信号中的信号!我们再来看一下。

    先来几个信号
    RACSubject * subjectOfSignal = [RACSubject subject]; RACSubject * subject1 = [RACSubject subject];

    然后我们发送信号
    [subjectOfSignal sendNext:subject1]; [subject1 sendNext:@"data1″];

    这边我们让一个信号发送数据,然后另一个信号发送这个信号。

    所以说 subjectOfSignal 就是我们的信号源~我们今天要拿到data1 又不能直接订阅signal1 的话就要对 subjectOfSignal 进行处理了!
    在第二篇中我们有说到过订阅信号中的信号用switchToLatest

    //创建多个信号
    RACSubject *signalOfSignal = [RACSubject subject];//信号中的信号
    RACSubject *signal1 = [RACSubject subject];
    
    [signalOfSignal.switchToLatest subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //发送信号
    [signalOfSignal sendNext:signal1];
    [signal1 sendNext:@"data"];
    
    

    这次我们说一个新的用法,那就是flattenMap来代替switchToLatest,如下

    [[signalOfSignal flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value) {
        return value;
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    

    二、RAC信号组合

    在我们开发中,比如一个页面不可能只会需要一个信号吧,这就需要用到我们RAC中的信号组合:
    1、concat 按照顺序组合的信号

    //RAC信号组合
    //1、concat 按照顺序组合的信号
    RACSignal * signal1 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        NSLog(@"发送请求 1");
        
        [subscriber sendNext:@"data1"];
        [subscriber sendCompleted]; //发送完毕
        return nil;
    }];
    
    RACSignal * signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        NSLog(@"发送请求 2");
        [subscriber sendNext:@"data2"];
        [subscriber sendCompleted]; //发送完毕
        return nil;
    }];
    
    RACSignal * signal3 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        NSLog(@"发送请求 3");
        [subscriber sendNext:@"data3"];
        [subscriber sendCompleted];
        return nil;
    }];
    
    
    [[RACSignal concat:@[signal3,signal2,signal1]] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    

    2、zipWith
    zip字面有压缩之意。
    多个信号组合,当他组合的两个信号,同时发送了信息头,他会回传一个元祖。
    开发中的需求比如让一个图片和名字同事显示。

    //zipWith: 多个信号组合,当他组合的两个信号,同时发送了信息头,他会回传一个元祖
    RACSubject * subject1 = [RACSubject subject];
    RACSubject * subject2 = [RACSubject subject];
    
    //压缩信号
    RACSignal * zipSignal = [subject1 zipWith:subject2];
    [zipSignal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    
    [subject1 sendNext:@"data1"];
    [subject2 sendNext:@"data2"];
    
    [subject1 sendNext:@"data11"];
    [subject2 sendNext:@"data22"];
    
    [subject1 sendNext:@"data111"];
    [subject2 sendNext:@"data222"];
    

    三、RAC忽略、过滤

    1、then 忽略

    //then 忽略
        RACSignal * signal1 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            
            NSLog(@"发送请求 1");
            
            [subscriber sendNext:@"data1"];
            [subscriber sendCompleted];
            return nil;
        }];
        
        RACSignal * signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            
            NSLog(@"发送请求 2");
            [subscriber sendNext:@"data2"];
            
            return nil;
        }];
        //当signal1 发送完毕后  忽略  data1 发送 signal2
        [[signal1 then:^RACSignal * _Nonnull{
            return signal2;
        }] subscribeNext:^(id  _Nullable x) {
            NSLog(@"%@",x);
        }];
    

    2、ignore指定忽略 某个/某些 信号

    // ignore
    RACSubject * subject = [RACSubject subject];
    //    忽略一些值
    //    [[subject ignore:@"data1"] subscribeNext:^(id  _Nullable x) {
    //        NSLog(@"%@",x);
    //    }];
    //    忽略所有值
    //    [[subject ignoreValues] subscribeNext:^(id  _Nullable x) {
    //        NSLog(@"%@",x);
    //    }];
    //    忽略某些值
    [[[subject ignore:@"data1"] ignore:@"data2"] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
        //打印出来的只有data3
    }];
    
    [subject sendNext:@"data1"];
    [subject sendNext:@"data2"];
    [subject sendNext:@"data3"];
    

    3、take指定订阅,忽略掉其他的
    take : 指定订阅(从前到后)前几个
    takeLast: (从后到前) 后几个

    //take
    RACSubject * subject  = [RACSubject subject];
    
    //take : 指定订阅(从前到后)前几个
    [[subject take:3] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
        //打印:data1,data2,data3
    }];
    
    //takeLast: (从后到前) 后几个
    [[subject takeLast:2] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
        //打印:data3,data4
    }];
    
    [subject sendNext:@"data1"];
    [subject sendNext:@"data2"];
    [subject sendNext:@"data3"];
    [subject sendNext:@"data4"];
    [subject sendCompleted];
    

    4、take的高级用法takeUntil
    字面意思直到

    //take的高级用法takeUntil直到
    RACSubject * subject1 = [RACSubject subject];
    RACSubject * subject2 = [RACSubject subject];
    [[subject1 takeUntil:subject2] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
        //打印:data1,data2,data3
    }];
    
    [subject1 sendNext:@"data1"];
    [subject1 sendNext:@"data2"];
    [subject1 sendNext:@"data3"];
    [subject2 sendNext:@"STOP"];
    [subject1 sendNext:@"data4"];
    

    5、distinctUntilChange 过滤到重复的信号
    在我们实际开发中有很多重复的信号,这就用到过滤的高级用法distinctUntilChange

    //distinctUntilChange 过滤到重复的信号
    RACSubject * subject1 = [RACSubject subject];
    
    
    [[subject1 distinctUntilChanged] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
        //打印 : data1 data12
    }];
    
    [subject1 sendNext:@"data1"];
    [subject1 sendNext:@"data1"];
    [subject1 sendNext:@"data12"];
    [subject1 sendNext:@"data12"];
    

    以上就是RAC中主要的一些用法了,要想掌握主要还是需要平时多练多写,不理解的点进去看看源代码,捋一下!

    上述代码可以到我的GitHub中下载

    有错误,有问题的欢迎提出来!😊

    相关文章

      网友评论

          本文标题:ReactiveCocoa(3)高级用法

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