美文网首页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 Day2 项目中常见的用法

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