RAC快速入门

RAC Day2 项目中常见的用法

2020-10-15  本文已影响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 *tuple = RACTuplePack(@"1", @2);//包装多值多类型数据
    RACTupleUnpack(NSString *value, NSNumber *value2) = tuple;//解包
    NSLog(@"value = %@, value2 = %@", value, value2);
    //创建一个发送多值多类型的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");
            }];
        }];
        //信号联合 执行有先后顺序 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 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");
        }];
    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实现的其他方法
//    - (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 用于高阶信号
    //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"];
    RACDisposable *dispose = [[RACSignal
                               interval:1
                               onScheduler:[RACScheduler scheduler]]
                              subscribeNext:^(NSDate * _Nullable x) {
        NSLog(@"每1秒执行 = %@", x);
    }];
    
    [RACScheduler.mainThreadScheduler afterDelay:1 schedule:^{
        NSLog(@"主线程中延迟1s执行");
    }];
上一篇 下一篇

猜你喜欢

热点阅读