美文网首页
RAC API使用

RAC API使用

作者: lmfei | 来源:发表于2019-10-22 14:32 被阅读0次

    RAC的定义

    ReactiveCocoa(简称:RAC),其具有函数式编程和响应式编程的特性,是github开源的一套开源框架

    RAC的作用

    • 解决开发中状态与状态之间的过多依赖
    • 解决MVC中Controller过于臃肿的问题
    • 提供统一的消息传递机制
    • 使代码高聚合,方便管理

    RAC的编程思想

    函数响应式编程(FRP)框架、将一切转换为信号


    万物皆信号
    注意:RAC通过weakify、strongify解决循环引用问题

    RAC的API

    集合类型的遍历

    -(void)rac_sequence {
        NSArray *array = @[@"111",@"222",@"333"];
        //遍历数组
        [array.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_array__%@",x);
        }];
        
        NSDictionary *dict = @{@"name":@"lmf",@"age":@"18"};
        [dict.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
            //Tuple:元祖
            //使用方式类似Array
            RACTwoTuple *tuple = x;
            NSLog(@"rac_dict__%@:%@",tuple[0],tuple[1]);
        }];
    }
    

    timer

    - (void)rac_timer {
        [[RACSignal interval:1 onScheduler: [RACScheduler schedulerWithPriority:(RACSchedulerPriorityHigh) name:@"com.lmf.rac_timer"]] subscribeNext:^(NSDate * _Nullable x) {
            NSLog(@"rac_timer______%@",x);
        }];
    }
    

    基础UI&&手势

    - (void)rac_ui {
        //button
        [[self.button rac_signalForControlEvents:(UIControlEventTouchUpInside)] subscribeNext:^(__kindof UIControl * _Nullable x) {
            NSLog(@"rac_button1:%@",x);
        }];
        
        self.button.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
            NSLog(@"rac_button2:%@",input);
            return [RACSignal empty];
        }];
        
        //textField
        [self.textField.rac_textSignal subscribeNext:^(NSString * _Nullable x) {
            NSLog(@"rac_textField:%@", x);
        }];
        
        //tap
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]init];
        self.label.userInteractionEnabled = YES;
        [self.label addGestureRecognizer:tap];
        [tap.rac_gestureSignal subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
            NSLog(@"rac_tap:%@",x);
        }];
    }
    

    通知

    - (void)rac_notify {
        [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
            NSLog(@"rac_notification:%@", x);
        }];
    }
    

    代理

    - (void)rac_delegate {
        self.textField.delegate = self;
        [[self rac_signalForSelector:@selector(textFieldDidBeginEditing:) fromProtocol:@protocol(UITextFieldDelegate)] subscribeNext:^(RACTuple * _Nullable x) {
            NSLog(@"rac_delegate:%@",x);
        }];
    }
    

    KVO

    - (void)rac_kvo {
        [RACObserve(self, name) subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_kvo:%@",x);
        }];
        self.name = @"lmf";
    }
    

    RAC

    把一个对象的某个属性绑定一个信号,只要发出信号,就会把信号的内容给对象的属性赋值
    - (void)rac_rac {
        RAC(self.label, text) = self.textField.rac_textSignal;
        /*
         //等同于
         [self.textField.rac_textSignal subscribeNext:^(id x) {
         self.label.text = x;
         }];
         */
    }
    

    signal

    - (void)rac_signal {
        RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            NSLog(@"createSignal");
            [subscriber sendNext:@"发送信号"];
            [subscriber sendError:[NSError errorWithDomain:@"baidu" code:404 userInfo:nil]];
            return [RACDisposable disposableWithBlock:^{
                
                NSLog(@"销毁了");
            }];
        }];
        
        [signal subscribeNext:^(id  _Nullable x) {
            NSLog(@"subscribeNext:%@",x);
        }];
        
        [signal subscribeError:^(NSError * _Nullable error) {
            NSLog(@"subscribeError:%@", error);
        }];
    }
    

    retry

    只要任务失败就会重新执行创建信号中的block的,直到成功
    - (void)rac_retry {
        __block int num = 0;
        [[[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            if (num == 10) {
                [subscriber sendNext:@10];
            }else {
                num ++;
                [subscriber sendError:[NSError errorWithDomain:@"baidu" code:-1 userInfo:nil]];
            }
            return nil;
        }] retry] subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_retry_next:%@",x);
        } error:^(NSError * _Nullable error) {
            NSLog(@"rac_retry_error:%@",error);
        }];
        
    }
    

    信号超时处理

    - (void)rac_timeout {
        RACSignal *signal = [[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            return nil;
        }] timeout:1 onScheduler:[RACScheduler currentScheduler]];
        [signal subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_timeout_subscribeNext:%@",x);
        } error:^(NSError * _Nullable error) {
            //超时会执行这段代码
            NSLog(@"rac_timeout_error:%@",error);
        }];
    }
    

    switchToLastest

    只能用于信号中的信号;获取信号中信号最近发出信号,订阅最近发出的信号
    - (void)rac_switchToLastest {
        RACSubject *signalOfSignals = [RACSubject subject];
        RACSubject *signal = [RACSubject subject];
        RACSubject *signal2 = [RACSubject subject];
        [signalOfSignals.switchToLatest subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_switchToLastest:%@",x);
        }];
        [signalOfSignals sendNext:signal2];
        [signalOfSignals sendNext:signal];
        [signal sendNext:@"hahaha"];
        [signal2 sendNext:@"12345"];
    }
    

    takeUntil

    当takeUntil传入的信号发出信号或者sendCompleted后,源信号将不再接受信号消息
    - (void)rac_takeUntil {
        RACSubject *subject = [RACSubject subject];
        RACSubject *subject2 = [RACSubject subject];
        [[subject takeUntil:subject2] subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_takeUntil:%@",x);
        }];
        [subject sendNext:@1];
        [subject sendNext:@2];
    //    [subject2 sendNext:@3];
        [subject2 sendCompleted];
        [subject sendNext:@4];
        [subject2 sendNext:@5];
        [subject sendNext:@6];
    }
    

    take&&takeLast

    take和takeLast使用方式一样,take取前x个信号,takeLast取后x个信号,takeLast使用后需要使用sendCompleted,告诉takeLast发送完成
    - (void)rac_takeLast {
        RACSubject *subject = [RACSubject subject];
        [[subject takeLast:2] subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_takeLast:%@",x);
        }];
        
        [subject sendNext:@1];
        [subject sendNext:@2];
        [subject sendNext:@3];
        [subject sendCompleted];
    }
    

    skip

    跳过前x个信号
    - (void)rac_skip {
        [[self.textField.rac_textSignal skip:1] subscribeNext:^(NSString * _Nullable x) {
            NSLog(@"rac_skip:%@",x);
        }];
    }
    

    distinctUntilChanged

    两次内容不一致就会发出信号,否则被忽略
    - (void)rac_distinctUntilChanged {
        RACSubject *subject = [RACSubject subject];
        [[subject distinctUntilChanged] subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_distinctUntilChanged:%@",x);
        }];
        
        [subject sendNext:@1];
        [subject sendNext:@1];
        [subject sendNext:@2];
        [subject sendNext:@2];
    }
    

    ignore

    忽略传入的信号
    - (void)rac_ignore {
    //    [[self.textField.rac_textSignal ignore:@"2"] subscribeNext:^(NSString * _Nullable x) {
    //        NSLog(@"rac_ignore:%@",x);
    //    }];
        
        RACSubject *subject = [RACSubject subject];
        [[subject ignore:@2] subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_ignore:%@",x);
        }];
        [subject sendNext:@1];
        [subject sendNext:@2];
        [subject sendNext:@3];
    }
    

    filter

    在发送信号前,先执行过滤条件,返回true,在发送信号
    - (void)rac_filter {
        RACSubject *subject = [RACSubject subject];
        [[subject filter:^BOOL(id  _Nullable value) {
            NSString *str = value;
            return str.length > 6;
        }] subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_filter:%@",x);
        }];
        [subject sendNext:@"1"];
        [subject sendNext:@"22"];
        [subject sendNext:@"666666"];
        [subject sendNext:@"7777777"];
    }
    

    reduce

    信号组合后,每次有信号发出,先执行block进行组合,再发送信号
    reduce block注意事项:
    参数:有多少信号组合,block就有多少个参数,每个参数就是之前信号发出的内容
    返回值:组合后的内容
    - (void)rac_reduce {
        
        RACSignal *signal1 = self.textField.rac_textSignal;
        RACSignal *signal2 = [self.button rac_signalForControlEvents:(UIControlEventTouchUpInside)];
        RACSignal *reduceSignal = [RACSignal combineLatest:@[signal1, signal2] reduce:^(id value1, id value2){
            return [NSString stringWithFormat:@"组合reduce == 1:%@ 2:%@", value1, value2];
        }];
        [reduceSignal subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_reduce:%@",x);
        }];
    }
    

    combineLatestWith

    当组合信号被订阅,内部会自动订阅多个信号,必须多个信号都被触发才会触发合并信号,并会把多个信号的值组合成元祖返回
    - (void)rac_combineLast {
        RACSignal *signal1 = self.textField.rac_textSignal;
        RACSignal *signal2 = [self.button rac_signalForControlEvents:(UIControlEventTouchUpInside)];
        
        RACSignal *comSignal = [signal1 combineLatestWith:signal2];
        [comSignal subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_combineLast:%@",x);
        }];
    }
    

    zip(不太明白)

    每当signalA或者signalB发出信号,就会判断signalA,signalB有没有发出个信号,有就会把最近发出的信号都包装成元组发出
    - (void)rac_zip {
        RACSignal *signal1 = self.textField.rac_textSignal;
        RACSignal *signal2 = [self.button rac_signalForControlEvents:(UIControlEventTouchUpInside)];
        RACSignal *zipSignal = [signal1 zipWith:signal2];
        [zipSignal subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_zip:%@",x);
        }];
    }
    

    merge

    把多个信号合并成一个信号,任何一个信号发送数据,都可以监听到
    - (void)rac_merge {
        RACSignal *signal1 = self.textField.rac_textSignal;
        RACSignal *signal2 = [self.button rac_signalForControlEvents:(UIControlEventTouchUpInside)];
        
        RACSignal *mergeSignal = [signal1 merge:signal2];
        [mergeSignal subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_merge:%@",x);
        }];
    }
    

    then

    第一个信号必须执行sendCompleted 第二个信号才会触发,监听的是第二个信号的值
    - (void)rac_then {
        [[[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
    //        [subscriber sendNext:@(123)];
            [subscriber sendCompleted];
            return nil;
        }] then:^RACSignal * _Nonnull{
            return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
                [subscriber sendNext:@(456)];
                [subscriber sendCompleted];
                return nil;
            }];
        }] subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_then:%@",x);
        }];
    }
    

    contact

    先监听前一个信号,再监听后面的信号
    - (void)rac_contact {
        RACSignal *signal1 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            [subscriber sendNext:@(123)];
            [subscriber sendCompleted];
            return nil;
        }];
        RACSignal *signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            [subscriber sendNext:@(456)];
            [subscriber sendCompleted];
            return nil;
        }];
        RACSignal *contactSignal = [signal1 concat:signal2];
        [contactSignal subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_contact:%@",x);
        }];
    }
    

    bind

    需要单独导入RACReturnSignal.h
    - (void)rac_bind {
        [[self.textField.rac_textSignal bind:^RACSignalBindBlock _Nonnull{
            return ^RACSignal *(id value, BOOL *sotp) {
                return [RACReturnSignal return:[NSString stringWithFormat:@"输出结果%@", value]];
            };
        }] subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_bind:%@",x);
        }];
    }
    

    map

    将源信息做了处理
    - (void)rac_map {
        [[self.textField.rac_textSignal map:^id _Nullable(NSString * _Nullable value) {
            return [NSString stringWithFormat:@"nb_%@",value];
        }] subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_map:%@",x);
        }];
    }
    

    flattenMap

    作用好像和map类似 都是对源信号进行了转换
    - (void)rac_flattenMap {
        [[self.textField.rac_textSignal flattenMap:^__kindof RACSignal * _Nullable(NSString * _Nullable value) {
            return [RACReturnSignal return:[NSString stringWithFormat:@"输出结果:%@",value]];
        }] subscribeNext:^(id  _Nullable x) {
            NSLog(@"rac_flattenMap:%@",x);
        }];
    }
    

    RACMulticastConnection

    当有多个订阅者时,按传统写法会发送多次信号,这时我们可以通过RACMulticatConnection,来解决
    - (void) rac_multicastConnection {
        /*
         // 普通写法, 这样的缺点是:每订阅一次信号就得重新创建并发送请求
         RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
         // 发送信号
         [subscriber sendNext:@"我是信号"];
         return nil;
         }];
         [signal subscribeNext:^(id x) {
         NSLog(@"%@", x);
         }];
         [signal subscribeNext:^(id x) {
         NSLog(@"%@", x);
         }];
         [signal subscribeNext:^(id x) {
         NSLog(@"%@", x);
         }];
         */
        // 比较好的做法:使用RACMulticastConnection,无论订阅多少次,只发送一次
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            // 发送信号
            [subscriber sendNext:@"我是信号"];
            return nil;
        }];
        RACMulticastConnection *connection = [signal publish];
        [connection.signal subscribeNext:^(id x) {
            NSLog(@"1:%@", x);
        }];
        [connection.signal subscribeNext:^(id x) {
            NSLog(@"2:%@", x);
        }];
        [connection.signal subscribeNext:^(id x) {
            NSLog(@"3:%@", x);
        }];
        //进行连接
        [connection connect];
    }
    

    RACCommand

    RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程
    - (void) rac_command {
        //创建命令
        RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
            NSLog(@"%@", input);
            return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
                [subscriber sendNext:@"额 我是谁"];
                //¥¥¥处使用
                [subscriber sendCompleted];
                return nil;
            }];
        }];
        
        /*
         //方式一:先获取执行命令返回的信号再订阅
         RACSignal *singnal = [command execute:@111];
         [singnal subscribeNext:^(id  _Nullable x) {
         NSLog(@"这是什么:%@",x);
         }];
         */
    
        /*
         //方式二:要先订阅再执行命令
         [command.executionSignals subscribeNext:^(id  _Nullable x) {
         [x subscribeNext:^(id  _Nullable x) {
         NSLog(@"这是啥:%@",x);
         }];
         }];
    
         [command execute:@222];
         */
    
        /*
         //方式三:要先订阅再执行命令,订阅方式有差异
         [command.executionSignals.switchToLatest subscribeNext:^(id  _Nullable x) {
         NSLog(@"这是啥:%@",x);
         }];
         [command execute:@333];
         */
        
        //¥¥¥
        [command.executing subscribeNext:^(NSNumber * _Nullable x) {
            if ([x boolValue] == YES) {
                NSLog(@"正在执行:%@", x);
            }
            else {
                NSLog(@"执行完成或者没有执行");
            }
        }];
        [command execute:@444];
    }
    

    生活如此美好,今天就点到为止。。。

    相关文章

      网友评论

          本文标题:RAC API使用

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