美文网首页
RAC(三)

RAC(三)

作者: dandelionYD | 来源:发表于2018-12-28 19:32 被阅读0次

    本demo详见github

    1.RAC过滤

    RACFilter_.m
    #import "RACFilter_.h"
    #import <ReactiveObjC.h>
    
    @interface RACFilter_ ()
    @property (nonatomic,strong)UITextField  *textF;
    @end
    
    @implementation RACFilter_
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.textF = [[UITextField alloc]initWithFrame:CGRectMake(10, 100, 500, 60)];
        self.textF.backgroundColor = [UIColor greenColor];
        self.textF.placeholder = @"请输入内容";
        [self.view addSubview:self.textF];
    //    [self skip];
    //    [self distinctUntilChanged];
    //    [self take];
    //    [self takeLast];
    //    [self takeUntil];
    //    [self ignore];
        [self fliter];
    }
    
    -(void)skip{
        //skip传入2 跳过前面两个值
        //实际用处: 在实际开发中比如 后台返回的数据前面几个没用,我们想跳跃过去,便可以用skip
        RACSubject *subject = [RACSubject subject];
        [[subject skip:2] subscribeNext:^(id  _Nullable x) {
            NSLog(@"%@",x);
        }];
        [subject sendNext:@1];
        [subject sendNext:@2];
        [subject sendNext:@3];
        //3
    }
    
    -(void)distinctUntilChanged {
        //如果当前的值跟上一次的值一样,就不会被订阅到
        RACSubject *subject = [RACSubject subject];
        [[subject distinctUntilChanged] subscribeNext:^(id  _Nullable x) {
            NSLog(@"%@",x);
        }];
        [subject sendNext:@1];
        [subject sendNext:@2];
        [subject sendNext:@2];
        //1 2
    }
    
    -(void)take{
        //take:可以屏蔽一些值,取面几个值---这里take为2 则只拿到前两个值
        RACSubject *subject = [RACSubject subject];
        [[subject take:2] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        // 发送信号
        [subject sendNext:@1];
        [subject sendNext:@2];
        [subject sendNext:@3];
        //1 2
    }
    
    - (void)takeLast {
        //takeLast:和take的用法一样,不过他取的是最后的几个值,如下,则取的是最后两个值
        //注意点:takeLast 一定要调用sendCompleted,告诉他发送完成了,这样才能取到最后的几个值
        RACSubject *subject = [RACSubject subject];
        [[subject takeLast:2] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        // 发送信号
        [subject sendNext:@1];
        [subject sendNext:@2];
        [subject sendNext:@3];
        [subject sendCompleted];
        
        //2 3
    }
    
    
    -(void)takeUntil{
        //takeUntil:---给takeUntil传的是哪个信号,那么当这个信号发送信号或sendCompleted,就不能再接受源信号的内容了(该信号也不发出)
        RACSubject *subject = [RACSubject subject];
        RACSubject *subject2 = [RACSubject subject];
        [[subject takeUntil:subject2] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        // 发送信号
        [subject sendNext:@1];
        [subject sendNext:@2];
        [subject2 sendNext:@3];  //输出:1 2
    //    [subject2 sendCompleted]; //输出:1 2
        [subject sendNext:@4];
    }
    
    
    - (void)ignore {
        //ignore:忽略一些值
        //ignoreValues:表示忽略所有的值
        // 1.创建信号
        RACSubject *subject = [RACSubject subject];
        // 2.忽略一些值
        RACSignal *ignoreSignal = [subject ignore:@2]; // ignoreValues:表示忽略所有的值
        // 3.订阅信号
        [ignoreSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        // 4.发送数据
        [subject sendNext:@2];
        [subject sendNext:@1];
        [subject sendNext:@2];
        //1  忽略了2
    }
    
    
    -(void)fliter{
        // 只有当文本框的内容长度大于5,才获取文本框里的内容
        [[self.textF.rac_textSignal filter:^BOOL(id value) {
            // value 源信号的内容
            return [value length] > 5;
            // 返回值 就是过滤条件。只有满足这个条件才能获取到内容
        }] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
    }
    @end
    
    

    2.RAC映射

    #import "Mapping_.h"
    #import <ReactiveObjC.h>
    #import <ReactiveObjC/RACReturnSignal.h>
    
    @interface Mapping_ ()
    
    @end
    
    @implementation Mapping_
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    //    [self map];
    //    [self flatMap];
    //    [self flattenMap2_way1];
    //    [self flattenMap2_way2];
        [self flattenMap2_way3];
    //    [self flattenMap2_way4];
    }
    
    - (void)map {
        // 创建信号
        RACSubject *subject = [RACSubject subject];
        // 绑定信号
        RACSignal *bindSignal = [subject map:^id(id value) {
            // 返回的类型就是你需要映射的值
            return [NSString stringWithFormat:@"映射处理啦:%@", value]; //这里将源信号发送的“123” 前面拼接了ws:
        }];
        // 订阅绑定信号
        [bindSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        // 发送信号
        [subject sendNext:@"123"];
        
        //映射处理啦:123
    }
    
    
    - (void)flatMap {
        // 创建信号
        RACSubject *subject = [RACSubject subject];
        // 绑定信号
        RACSignal *bindSignal = [subject flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value) {
            // block:只要源信号发送内容就会调用
            // value: 就是源信号发送的内容
            // 返回信号用来包装成修改内容的值
            NSString *changevalue = [NSString stringWithFormat:@"改变下值:%@",value];
            return [RACReturnSignal return:changevalue];
        }];
        
        // flattenMap中返回的是什么信号,订阅的就是什么信号(那么,x的值等于value的值,如果我们操纵value的值那么x也会随之而变)
        // 订阅信号
        [bindSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        // 发送数据
        [subject sendNext:@"123"];
        
        //改变下值:123
    }
    
    
    - (void)flattenMap2_way1 {
        // flattenMap 主要用于信号中的信号
        // 创建信号
        RACSubject *signalofSignals = [RACSubject subject];
        RACSubject *signal = [RACSubject subject];
        [signalofSignals subscribeNext:^(id x) {
            [x subscribeNext:^(id x) {
                NSLog(@"%@", x);
            }];
        }];
        // 发送信号
        [signalofSignals sendNext:signal];
        [signal sendNext:@"123"];
    }
    
    - (void)flattenMap2_way2 {
        // 创建信号
        RACSubject *signalofSignals = [RACSubject subject];
        RACSubject *signal = [RACSubject subject];
        [signalofSignals.switchToLatest  subscribeNext:^(id  _Nullable x) {
            NSLog(@"%@",x);
        }];
        // 发送信号
        [signalofSignals sendNext:signal];
        [signal sendNext:@"123"];
    }
    
    - (void)flattenMap2_way3 {
        // flattenMap 主要用于信号中的信号
        // 创建信号
        RACSubject *signalofSignals = [RACSubject subject];
        RACSubject *signal = [RACSubject subject];
        RACSignal *bignSignal = [signalofSignals flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value){
            //value:就是源信号发送内容
            return value;
        }];
        [bignSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        // 发送信号
        [signalofSignals sendNext:signal];
        [signal sendNext:@"123"];
    }
    
    //方式4:开发中常用的
    - (void)flattenMap2_way4 {
        // flattenMap 主要用于信号中的信号
        // 创建信号
        RACSubject *signalofSignals = [RACSubject subject];
        RACSubject *signal = [RACSubject subject];
        [[signalofSignals flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value) {
            return value;
        }] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        // 发送信号
        [signalofSignals sendNext:signal];
        [signal sendNext:@"123"];
    }
    
    @end
    

    3.RAC组合

    #import "RACCombination_.h"
    #import <ReactiveObjC.h>
    
    @interface RACCombination_ ()
    @property (nonatomic,strong)UITextField  *accountF;
    @property (nonatomic,strong)UITextField  *pwdF;
    @property (nonatomic,strong)UIButton  *loginBtn;
    @end
    
    @implementation RACCombination_
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.accountF = [[UITextField alloc]initWithFrame:CGRectMake(10, 100, 200, 40)];
        [self.view addSubview:self.accountF];
        self.accountF.placeholder = @"账号输入";
        self.pwdF = [[UITextField alloc]initWithFrame:CGRectMake(10, 200, 200, 40)];
        [self.view addSubview:self.pwdF];
        self.pwdF.placeholder = @"密码输入";
        self.loginBtn = [[UIButton alloc]initWithFrame:CGRectMake(10, 300, 200, 40)];
        [self.view addSubview:self.loginBtn];
        self.loginBtn.backgroundColor = [UIColor redColor];
        
    //    [self combineLatest];
        
    //    [self zipWith];
        
    //    [self merge];
        
    //    [self then];
        
        [self concat];
        
        
    }
    
    - (void)combineLatest {
        RACSignal *combinSignal = [RACSignal combineLatest:@[self.accountF.rac_textSignal, self.pwdF.rac_textSignal] reduce:^id(NSString *account, NSString *pwd){ //reduce里的参数一定要和combineLatest数组里的一一对应。
            // block: 只要源信号发送内容,就会调用,组合成一个新值。
            NSLog(@"%@ %@", account, pwd);
            return @(account.length && pwd.length);
        }];
        
        // 订阅信号
        //    [combinSignal subscribeNext:^(id x) {
        //        self.loginBtn.enabled = [x boolValue];
        //    }];    // ----这样写有些麻烦,可以直接用RAC宏
        RAC(self.loginBtn, enabled) = combinSignal;
    }
    
    
    - (void)zipWith {
        //zipWith:把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元祖,才会触发压缩流的next事件。
        // 创建信号A
        RACSubject *signalA = [RACSubject subject];
        // 创建信号B
        RACSubject *signalB = [RACSubject subject];
        // 压缩成一个信号
        // **-zipWith-**: 当一个界面多个请求的时候,要等所有请求完成才更新UI
        // 等所有信号都发送内容的时候才会调用
        RACSignal *zipSignal = [signalA zipWith:signalB];
        [zipSignal subscribeNext:^(id x) {
            NSLog(@"%@", x); //所有的值都被包装成了元组
        }];
        // 发送信号 交互顺序,元组内元素的顺序不会变,跟发送的顺序无关,而是跟压缩的顺序有关[signalA zipWith:signalB]---先是A后是B
        [signalA sendNext:@1];
        [signalB sendNext:@2];
        
        // <RACTwoTuple: 0x600001432780> (1,2)
    }
    
    
    // 任何一个信号请求完成都会被订阅到
    // merge:多个信号合并成一个信号,任何一个信号有新值就会调用
    - (void)merge {
        // 创建信号A
        RACSubject *signalA = [RACSubject subject];
        // 创建信号B
        RACSubject *signalB = [RACSubject subject];
        //组合信号
        RACSignal *mergeSignal = [signalA merge:signalB];
        // 订阅信号
        [mergeSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        // 发送信号---交换位置则数据结果顺序也会交换
        [signalB sendNext:@"下部分"];
        [signalA sendNext:@"上部分"];
        
        //下部分
        //上部分
    }
    
    
    // then --- 使用需求:有两部分数据:想让上部分先进行网络请求但是过滤掉数据,然后进行下部分的,拿到下部分数据
    - (void)then {
        // 创建信号A
        RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            // 发送请求
            NSLog(@"----发送上部分请求---afn");
            
            //模拟网络请求
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                  [subscriber sendCompleted]; // 必须要调用sendCompleted方法!
            });
            return nil;
        }];
        
        // 创建信号B,
        RACSignal *signalsB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            // 发送请求
            NSLog(@"--发送下部分请求--afn");
            [subscriber sendNext:@"下部分数据"];
            return nil;
        }];
        // 创建组合信号
        // then;忽略掉第一个信号的所有值
        RACSignal *thenSignal = [signalA then:^RACSignal *{
            // 返回的信号就是要组合的信号
            return signalsB;
        }];
        
        // 订阅信号
        [thenSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
    }
    
    
    // concat----- 使用需求:有两部分数据:想让上部分先执行,完了之后再让下部分执行(都可获取值)
    - (void)concat {
        // 创建信号A
        RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            // 发送请求
            NSLog(@"----发送上部分请求---afn");
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [subscriber sendNext:@"上部分数据"];
                [subscriber sendCompleted]; // 必须要调用sendCompleted方法!
            });
            return nil;
        }];
        
        // 创建信号B,
        RACSignal *signalsB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            // 发送请求
            NSLog(@"--发送下部分请求--afn");
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [subscriber sendNext:@"下部分数据"];
            });
            return nil;
        }];
        
        // concat:按顺序去链接
        //**-注意-**:concat,第一个信号必须要调用sendCompleted
        // 创建组合信号
        RACSignal *concatSignal = [signalA concat:signalsB];
        // 订阅组合信号
        [concatSignal subscribeNext:^(id x) {
            NSLog(@"%@",x);
        }];
        
    }
    
    @end
    

    4.RACBind

    #import "RACBind_.h"
    #import <ReactiveObjC.h>
    #import <ReactiveObjC/RACReturnSignal.h>
    
    @interface RACBind_ ()
    @end
    
    @implementation RACBind_
    - (void)viewDidLoad {
        [super viewDidLoad];
        // 1.创建信号
        RACSubject *subject = [RACSubject subject];
        // 2.绑定信号
        RACSignal *bindSignal = [subject bind:^RACSignalBindBlock{
            // block调用时刻:只要绑定信号订阅就会调用。不做什么事情,
            return ^RACSignal *(id value, BOOL *stop){
                // 一般在这个block中做事 ,发数据的时候会来到这个block。
                // 只要源信号(subject)发送数据,就会调用block
                // block作用:处理源信号内容
                // value:源信号发送的内容,
    
                
                //这一行也可以注销哟(注销就是123哟)
                value = @3; // 如果在这里把value的值改了,那么订阅绑定信号的值即41行的x就变了
                
                
                NSLog(@"接受到源信号的内容:%@", value);
                //返回信号,不能为nil,如果非要返回空---则empty或 alloc init。
                return [RACReturnSignal return:value]; // 把返回的值包装成信号
            };
        }];
        
        // 3.订阅绑定信号
        [bindSignal subscribeNext:^(id x) {
            NSLog(@"接收到绑定信号处理完的信号:%@", x);
        }];
        // 4.发送信号
        [subject sendNext:@"123"];
    }
    //接受到源信号的内容:3
    //接收到绑定信号处理完的信号:3
    @end
    

    友情链接:

    相关文章

      网友评论

          本文标题:RAC(三)

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