美文网首页
ReactiveCocoa学习笔记

ReactiveCocoa学习笔记

作者: KallyKello | 来源:发表于2017-02-08 15:21 被阅读0次

    1、ReactiveCocoa中的类

    1、在RAC中最核心的类是RACSignal。RACSiganl是信号类,一般表示将来有数据传递,只有有数据改变,信号内部接收到数据,就会马上发出数据

    • 信号类(RACSiganl)只是表示当数据改变时,信号内部发出数据,他本身更不具备发送信号的能力,而是交给内部一个订阅者去发出
    • 默认一个信号都是冷信号,也就是值改变了,也不会触发,只有订阅了这个信号,这个信号才会变成热信号,值改变了才会触发
    • 如何订阅信号:调用信号RACSignal的subscribeNext就能订阅
        //1.创建信号
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            //block调用时刻:每当有订阅者订阅信号,就会电泳block
            //2.发出信号
            [subscriber sendNext:@1];
            
            //如果不发送数据,最好发送信号完成,内部会自动调用[RACDisposable disposable]取消订阅信号
            [subscriber sendCompleted];
            
            return [RACDisposable disposableWithBlock:^{
                //block调用时刻:当信号发送完成或者发送错误,就会自动执行这个block,取消订阅信息
                
                //执行完block后,当前信号就不会被订阅了。
                NSLog(@"信号被销毁");
                
            }];
        }];
        
        //3.订阅信号,才会激活信号
        [signal subscribeNext:^(id x) {
            NSLog(@"接收到数据%@",x);
        }];
    

    2、RACTuple:元组类,类似于NSArray。用来包装值
    RACSequence:RAC中的集合类,用于替代NSArray,NSDictionary,可以使用它来快速遍历数组合字典

        //1.遍历数组
        NSArray *numbers = @[@1,@2,@3,@4,@5];
        
        /*
            这里有三个步骤
            第一步:把数组转换成几个RACSequence numbers.rac_sequence
            第二步:把集合RACSequence转换RACSignal信号类,numbers.rac_sequence.signal
            第三步:订阅号,激活信号,会自动把集合中的所有值遍历出来
         */
        
        [numbers.rac_sequence.signal subscribeNext:^(id x) {
            NSLog(@"%@",x);
        }];
        
        //2.遍历字典
        NSDictionary *dict = @{@"name":@"xiaoming",@"age":@"15",@"sex":@"男",@"phone":@"18275317977"};
        
        [dict.rac_sequence.signal subscribeNext:^(id x) {
           //解包元组,会把元组的值,按顺序给参数里面的变量赋值
            RACTupleUnpack(NSString *key,NSString *value) = x;
            
            //类似于
            //NSString *key = x[0];
            //NSString *value = x[1];
            NSLog(@"key:%@ \t value:%@",key,value);
        }];
    

    3.RACCommand类是RAC中用于处理事件的类,可以把时间如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程,常用于监听按钮点击,网络请求

        //1.创建命令
        RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
            NSLog(@"执行命令");
            
            //signalBlock中必须返回一个信号,不能穿nil,如果不想传递信号,直接返回一个空信号
            //return [RACSignal empty];
            
            //2.创建信号,用来传递数据
            return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
                [subscriber sendNext:@"请求数据"];
                
                //注意:数据传递完,最好调用sendCompleted,这是命令才执行完成
                [subscriber sendCompleted];
                return nil;
            }];
        }];
        
        //2.强引用命令,不要被销毁,否则接收不到数据
        _command = command;
        
        //3.订阅RACCommend中的信号
    //    [command.executionSignals subscribeNext:^(id x) {
    //        [x subscribeNext:^(id x) {
    //            NSLog(@"%@",x);
    //        }];
    //    }];
        //RAC高级用法
        //switchToLatest:用于signal of signals,获取signal of signals 发出的最新信号。也就是可以直接那袋RACCommand的信号了
        [command.executionSignals.switchToLatest subscribeNext:^(id x) {
            NSLog(@"%@",x);
        }];
        
        //4.监听命令是否执行完毕,默认会再来一次,可以直接跳过,skip表示跳过第一次信号
        [[command.executing skip:1] subscribeNext:^(id x) {
            if ([x boolValue]) {
                //正在执行
                NSLog(@"正在执行");
            } else {
                //执行完成
                NSLog(@"执行完成");
            }
        }];
        
        //5.执行命令
        [self.command execute:@1];
    

    4.RACMulticastConnection用于当一个信号被多次订阅时,为了保证创建信号时,避免多次调用创建信号中的block,造成副作用,可以使用这个类处理。

    • RACMulticastConnection通过RACSignal的-publish或者-muticast方法创建
        //1.创建请求信号
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            NSLog(@"发出请求");
            return nil;
        }];
        
        //2.订阅信号1
        [signal subscribeNext:^(id x) {
            NSLog(@"接收数据");
        }];
        //2.订阅信号2
        [signal subscribeNext:^(id x) {
            NSLog(@"接收数据");
        }];
        //3.�运行结果,会执行两次发送请求,也就是每次订阅都会发送一次请求
        2017-02-08 11:23:00.883 ReactiveCocoaDemo[1045:36247] 发出请求
        2017-02-08 11:23:00.884 ReactiveCocoaDemo[1045:36247] 发出请求
        
        //RACMulticastConnection解决请求重复问题
        //1.创建信号
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            NSLog(@"发出请求");
            [subscriber sendNext:@1];
            return nil;
        }];
        //2.创建链接
        RACMulticastConnection *connection = [signal publish];
        
        //3.订阅信号
        //注意:订阅型号也不能激活信号,只是保存订阅者到数组,当调用链接,就会一次性调用所有订阅者的sendNext:
        [connection.signal subscribeNext:^(id x) {
            NSLog(@"订阅者一信号   %@",x);
        }];
        [connection.signal subscribeNext:^(id x) {
            NSLog(@"订阅者二信号   %@",x);
        }];
        
        //4.链接,激活信号
        [connection connect];
    

    2、ReactiveCocoa开发中常见用法

    1.替代代理

    • rac_signalFirSelector:用于替代代理
      2、替代kvo
    • rac_valuesAndChangesForKeyPath:用于监听某个对象的属性改变
      3、监听事件
    • rac_signalForControlEvents:用于监听某个事件
      4、代替通知
    • rac_addObsererForName:用于监听某个通知
      5、监听文本框文字改变
    • rac_textSignal:只要文本框发出改变就会发出这个信号。
      6、处理当界面又多次请求时,需要都获取到数据时,才能展示界面
    • rac_liftSelector:withSignalsFromArray:Signals:当传入的Signals(信号数组),每一个signal都至少sendNext过一次,就回去出发第一个selector参数的方法
    • 使用注意:几个信号,参数一的方法就是几个参数,每个参数对应信号发出的数据

    3、ReactiveCocoa常见的宏

    1、RAC(TARGET, [KEYPATH, [NIL_VALUE]])用于给某个对象的某个属性绑定

    //只要修改文本框文字,就会修改label的文字
    RAC(self.titleLable,text) = _textField.rac_textSignal;
    

    2、RACObserve(self, name)监听某个对象的某个属性,返回的是信号

    [RACObserve(self.view, center) subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }
    

    3、@weakify(Obj)@strongify(Obj),一般两个都是配套使用,在猪头文件(ReactiveCocoa.h)中并没有导入,余姚自己手动导入,RACEXTScope.h才可以使用。但是每次导入都非常麻烦,只需要在主头文件自己导入就好了
    4、RACTuplePack()把数据包装成RACTuple(元组类)

    //把参数中的数据包装成元组
    RACTuple *tuple = RACTuplePack(@10,@30);
    

    5、RACTupleUnpack()吧RACTuple解包成对应的数据

    //把参数中的数据包装成元组
    RACTuple *tuple = RACTuplePack(@10,@30);
    RACTupleUnpack(NSNumber *one,NSNumber *two) = tuple;
    

    相关文章

      网友评论

          本文标题:ReactiveCocoa学习笔记

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