ReactiveCocoa学习笔记

1、ReactiveCocoa中的类

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

  • 信号类(RACSiganl)只是表示当数据改变时,信号内部发出数据,他本身更不具备发送信号的能力,而是交给内部一个订阅者去发出
  • 默认一个信号都是冷信号,也就是值改变了,也不会触发,只有订阅了这个信号,这个信号才会变成热信号,值改变了才会触发
  • 如何订阅信号:调用信号RACSignal的subscribeNext就能订阅
    //1.创建信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id 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 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 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 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学习笔记)