美文网首页RAC快速入门
RAC Day2 项目中常见的用法

RAC Day2 项目中常见的用法

作者: 帅气的阿斌 | 来源:发表于2020-10-15 14:04 被阅读0次

首先创建一个基本的信号

    //创建一个基本的信号
    RACSignal *racignl = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        [subscriber sendNext:@"map1"];
        [subscriber sendNext:@"map2"];
        [subscriber sendCompleted];
        
        return [RACDisposable disposableWithBlock:^{
            ;
        }];
    }];

1.map(遍历映射):将原有的数据按照先后顺序映射成新值,常用于遍历数据进行类型或值的转换

    //map 根据现有值 映射出新值 map(1,2,3) => (1,4,9)
    //逻辑顺序 一个普通的 racignl 使用 map 生成一个新的 afterMapSignal; afterMapSignal订阅触发值传递
    //^id _Nullable(NSString *value) 返回值为id类型,传入参数为value的block
    RACSignal *afterMapSignal = [racignl map:^id _Nullable(NSString *value) {
        return [NSString stringWithFormat:@"%@==mapfix", value];
    }];
    [afterMapSignal subscribeNext:^(id  _Nullable x) {
        NSLog(@"after == %@", x);
    } error:^(NSError * _Nullable error) {
        ;
    } completed:^{
        ;
    }];

2.mapReplace(遍历替换):遍历原有的数据并替换成指定的值

    //- (RACSignal *)mapReplace:(nullable id)object
    //mapReplace 使用新值替换所有订阅传递的值
    RACSignal *replaceSignl = [racignl mapReplace:@"使用新值替换所有订阅传递的值"];
    [replaceSignl subscribeNext:^(id  _Nullable x) {
        NSLog(@"replace == %@", x);
    } error:^(NSError * _Nullable error) {
        ;
    } completed:^{
        ;
    }];

3.reduceEach

  • RACTuple RACTupleUnpack 的简单使用
    RACTuple *tuple = RACTuplePack(@"1", @2);//包装多值多类型数据
    RACTupleUnpack(NSString *value, NSNumber *value2) = tuple;//解包
    NSLog(@"value = %@, value2 = %@", value, value2);
  • reduceEach:是map的变体。你的sendNext可能要发送多个值,值类型不同也支持,此时数据就需要用RACTuple包裹
    //创建一个发送多值多类型的signl
    RACSignal *reduceEach = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        [subscriber sendNext:RACTuplePack(@"1", @11)];
        [subscriber sendNext:RACTuplePack(@"2", @22)];
        
        return [RACDisposable disposableWithBlock:^{
            ;
        }];
    }];

    RACSignal *reduceEachFinal = [reduceEach reduceEach:^id _Nonnull(NSString *value1, NSNumber *value2){
        return @([value1 integerValue] + [value2 integerValue]);
    }];
    [reduceEachFinal subscribeNext:^(id  _Nullable x) {
        NSLog(@" reduceEachFinal = %@", x);
    } error:^(NSError * _Nullable error) {
        ;
    } completed:^{
        ;
    }];

4.concatzipwith

  • 先创建两个信号
    /// 创建一个信号<默认都是冷信号 被监听了才会执行block>.
        RACSignal *racsignl = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            
            NSLog(@"准备发送信号");
            [subscriber sendNext:@"发送信号"];
            
            NSLog(@"准备发送信号2");
            [subscriber sendNext:@"发送信号2"];
            
            NSLog(@"准备 sendCompleted");
            [subscriber sendCompleted];
            
            NSLog(@"准备发送 Error");
            [subscriber sendError:[NSError new]];
            
            return [RACDisposable disposableWithBlock:^{
                NSLog(@"RACDisposable");
            }];
        }];
        
        
        [racsignl subscribeNext:^(id  _Nullable x) {
            NSLog(@"监听结果 %@", x);//从管道收到两条数据 1--发送信号 2--发送信号2--
        } error:^(NSError * _Nullable error) {
            NSLog(@"收到了 error");
        } completed:^{
            NSLog(@"收到了 sendCompleted");
        }];
        
        
        RACSignal *signl2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            
            NSLog(@"sign2 准备发送信号");
            [subscriber sendNext:@"sign2 发送信号"];
            
            NSLog(@"sign2 准备发送信号2");
            [subscriber sendNext:@"sign2 发送信号2"];
            
            NSLog(@"sign2 准备 sendCompleted");
            [subscriber sendCompleted];
            
            NSLog(@"sign2 准备发送 Error");
            [subscriber sendError:[NSError new]];
            
            return [RACDisposable disposableWithBlock:^{
                NSLog(@"sign2 RACDisposable");
            }];
        }];
  • concat
        //信号联合 执行有先后顺序 racsignl -> signl2   racsignl sendCompleted之后 signl2才会执行
        RACSignal *contacSignl = [racsignl concat:signl2];
        [contacSignl subscribeNext:^(id  _Nullable x) {
            NSLog(@"监听结果 %@", x);
        } error:^(NSError * _Nullable error) {
            NSLog(@"收到了 error");
        } completed:^{
            NSLog(@"收到了 sendCompleted");
        }];
  • zipwith:成对模式 信号1和信号2 的sendNext一一对应,多出的sendNext将被舍弃
        //zipwith sendNext一一对应 监听的结果为 RACTwoTuple 类型 不能一一对应的部分会被丢弃
    //    RACSignal *zipWithSignl = [racsignl zipWith:signl2]; //有执行顺序 racsignl -> signl2 但是subscribeNext执行是两者都执行了才会回调
        RACSignal *zipWithSignl = [signl2 zipWith:racsignl];
        [zipWithSignl subscribeNext:^(id  _Nullable x) {
            NSLog(@"监听结果 %@", x);
        } error:^(NSError * _Nullable error) {
            NSLog(@"收到了 error");
        } completed:^{
            NSLog(@"收到了 sendCompleted");
        }];
  • filter 过滤(筛选)
    RACSignal *filterSignl = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        [subscriber sendNext:@1];
        [subscriber sendNext:@2];
        [subscriber sendNext:@3];
        [subscriber sendNext:@4];
        [subscriber sendNext:@5];
        [subscriber sendNext:@6];
        [subscriber sendNext:@7];
        [subscriber sendNext:@8];
        [subscriber sendNext:@9];
        
        [subscriber sendCompleted];
        
        return [RACDisposable disposableWithBlock:^{
            NSLog(@" filterSignl RACDisposable ");
        }];
        
    }];
    //^BOOL(NSNumber *value) 返回值为BOOL类型 表示是否要过滤该值,value为遍历出来的原始值
    [[filterSignl filter:^BOOL(NSNumber *value) {
        return (value.integerValue > 5);//保留返回>5的值
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@" filter = %@", x);//输出过滤后符合条件的值
    }];
  • 通过filter实现的其他方法
//    通过filter实现的其他方法
//    - (RACSignal *)ignoreValues {
//        return [[self filter:^(id _) {
//            return NO;
//        }] setNameWithFormat:@"[%@] -ignoreValues", self.name];
//    }
//- ignoreValues
    [[filterSignl ignoreValues] subscribeNext:^(id  _Nullable x) {
        NSLog(@" ignoreValues = %@", x);
    }];
    
//    - (__kindof RACStream *)ignore:(id)value {
//        return [[self filter:^ BOOL (id innerValue) {
//            return innerValue != value && ![innerValue isEqual:value];
//        }] setNameWithFormat:@"[%@] -ignore: %@", self.name, RACDescription(value)];
//    }
//- ignore:
    [[filterSignl ignore:@3] subscribeNext:^(id  _Nullable x) {
        NSLog(@" ignore = %@", x);
    }];
    
//- distinctUntilChanged
//    [subscriber sendNext:@9];
//    [subscriber sendNext:@9];
//    [subscriber sendNext:@9];
//    [subscriber sendNext:@10];
    
    [[filterSignl distinctUntilChanged] subscribeNext:^(id  _Nullable x) {
        NSLog(@" distinctUntilChanged = %@", x);//9只会输出一次
    }];
    
//- take 接收信号中指定的值的个数 即:只接收到两个sendNext传过来的值
    [[filterSignl take:2] subscribeNext:^(id  _Nullable x) {
        NSLog(@" take = %@", x);
    }];
    //-takeUntil:一个信号的订阅会因为另一个信号的发送而立即取消订阅
    //以下列子
    //takeUntilSignlBtn按钮点击事件为一个信号 btn的点击事件也是一个信号 btn的点击信号被订阅 一旦takeUntilSignlBtn的点击事件信号发送
    //btn的信号订阅就会被取消
    
    UIButton *takeUntilSignlBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    takeUntilSignlBtn.titleLabel.numberOfLines = 2;
    [self.view addSubview:takeUntilSignlBtn];
    takeUntilSignlBtn.frame = CGRectMake(50, 160, 300, 80);
    [takeUntilSignlBtn setTitle:@"点击则发送作为 takeUntil 的信号" forState:UIControlStateNormal];
    [takeUntilSignlBtn setTitleColor:UIColor.redColor forState:UIControlStateNormal];
    //该按钮点击的信号
    RACSignal *takeUntilSignl = [takeUntilSignlBtn rac_signalForControlEvents:UIControlEventTouchUpInside];
    [takeUntilSignl subscribeNext:^(UIButton *x) {
        [x setTitle:@"你已经触发了takeUntilSignl信号 下面按钮点击信号订阅已被取消" forState:UIControlStateNormal];
    }];
    
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    btn.titleLabel.numberOfLines = 3;
    [self.view addSubview:btn];
    btn.frame = CGRectMake(50, 260, 300, 80);
    [btn setTitle:@"点击可获取订阅到的UIControlEventTouchUpInside" forState:UIControlStateNormal];
    [btn setTitleColor:UIColor.redColor forState:UIControlStateNormal];
    
    //rac_signalForControlEvents 创建一个监听 UIControlEventTouchUpInside 的信号
    //takeUntil的信号为```takeUntilSignlBtn```按钮的点击事件,也就是说订阅```btn```点击事件的信号在```takeUntilSignlBtn```的点击信号发送后取消订阅
    [[[btn rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:takeUntilSignl] subscribeNext:^(__kindof UIButton * _Nullable x) {
        [x setTitle:[NSString stringWithFormat:@"点击可获取订阅到的UIControlEventTouchUpInside=%d", rand()] forState:UIControlStateNormal];
    }];
  • switchToLatest仅用于高阶信号(高阶信号就是信号发送的也是信号)
    //switchToLatest 用于高阶信号
    //e.g:signls本身是个信号 sendNext: 发送的也是信号
    //switchToLatest
    //属于降阶操作 订阅结果是signls信号发送的signlA/signlB信号的sendNext的值
    //另外如果signls发送了另一个信号 则上个信号signlA则被取消订阅 而开始订阅下一个信号signlB
    
    //signls直接subscribeNext会看到接收到的就是signlA和signlB
    RACSubject *signls = [RACSubject subject];
    
    RACSubject *signlA = [RACSubject subject];
    RACSubject *signlB = [RACSubject subject];
        
    [signls.switchToLatest subscribeNext:^(id  _Nullable x) {
        NSLog(@" switchToLatest = %@", x);
    }];
    [signls subscribeNext:^(id  _Nullable x) {
        NSLog(@" signls subscribeNext = %@", x);
    }];
    
    [signls sendNext:signlA];
    [signlA sendNext:@"1"];
    [signlA sendNext:@"2"];
    
    [signls sendNext:signlB];
    
    [signlA sendNext:@"3"];//此时的signlA在 switchToLatest 的订阅已经被取消 所以不会打印该值
    
    [signlB sendNext:@"11"];
    [signlB sendNext:@"22"];
    [signlB sendNext:@"33"];
  • RAC的定时器(内部使用GCD实现)
    RACDisposable *dispose = [[RACSignal
                               interval:1
                               onScheduler:[RACScheduler scheduler]]
                              subscribeNext:^(NSDate * _Nullable x) {
        NSLog(@"每1秒执行 = %@", x);
    }];
    
    [RACScheduler.mainThreadScheduler afterDelay:1 schedule:^{
        NSLog(@"主线程中延迟1s执行");
    }];
  • 还有很多很多(常见的都已经列出) 后续有用到的再慢慢补充吧

相关文章

  • RAC常见用法(二)

    接着说RAC的常见用法 : 这是今天要说的几个常见用法: rac_liftSelector 当多个信号都被发送时,...

  • 记录ReactiveObjC的一些用法

    常见用法 rac_signalForSelector : 代替代理 rac_valuesAndChangesFor...

  • RAC Day2 项目中常见的用法

    首先创建一个基本的信号 1.map(遍历映射):将原有的数据按照先后顺序映射成新值,常用于遍历数据进行类型或值的转...

  • RAC一些常见用法(五)

    本demo详见github 1.常见的用法 2.RAC常见的宏 3.发送验证码 友情链接: RAC(一) RAC(...

  • RAC基本用法

    最近公司要用MVVM+RAC重构项目,所以就对RAC开发中的基本用法总结了一下。 RACSignal RACSig...

  • RAC的常见用法

    1. 代替代理: rac_signalForSelector:替代代理。 2. 代替KVO : rac_value...

  • RAC常见用法(三)

    本文将要介绍的RAC的常见用法大纲: RAC的映射: 首先看flattenMap:这个方法, 其实这个方法的内部是...

  • ReactiveCocoa (二) 之常见用法

    ReactiveCocoa开发中常见用法。 代替代理: rac_signalForSelector:用于替代代理。...

  • (转)ReactiveCocoa之RAC常见用法

    ReactiveCocoa开发中常见用法。 代替代理:rac_signalForSelector:用于替代代理。 ...

  • RAC常见用法(一)

    上次体验了一把RAC, 今天, 再介绍一下RAC的简单用法: 首先看一下打算介绍的知识点: 然后, 就开始One ...

网友评论

    本文标题:RAC Day2 项目中常见的用法

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