美文网首页iOS Developer
ReactiveCocoa 个人学习笔记记录(一)

ReactiveCocoa 个人学习笔记记录(一)

作者: 奥卡姆剃须刀 | 来源:发表于2016-10-18 10:47 被阅读316次
    WechatIMG7.jpeg

    之前就一直在看ReactiveCocoa 相关知识 但是有感觉每次看完收货甚微,且感觉零零散散 ,本blog 仅仅是记录自己的学习过程

    文章目录

    • 1 ReactiveCocoa 介绍
    • 2 ReactiveCocoa的应用场景
    • 3 ReactiveCocoa 被描述为函数式响应编程(FRP)框架
    • 4 如何添加ReactiveCocoa
    • 5 分析ReactiveCocoa中的常见类
      • 5-1 RACSignal:信号类
      • 5-2 RACSubscriber:订阅者
      • 5-3 RACDisposable:取消订阅
      • 5-4 RACSubject:信号提供者可发信号可充当信号
      • 5-5 RACTuple:元祖类 类似NSArray用来包装值
      • 5-6 RACSequence (Sequence:序列排序) :RAC中的集合类 用于代替NSArray 和 NSDictionary 可以使用它来快速遍历数组和字典
      • 5-7 RACCommand :RAC中用于处理事件的类, 可以吧事件如何处理,事件中的数据如何传递,包装到这个类中 他可以很方便的监控事件的执行过程
      • 5-8 RACMulticastConnection 用于当一个信号被多次订阅是为了保证创建信号时 避免多次调用创建信号中的block 造成副作用 可以使用这个类创建
    • 5-9 RACScheduler :RAC中的队列 用GCD封装的
    • 5-10 RACUnit :表示Stream不包含有意义的值 也就是看到这个 可以直接理解为nil
    • 6 ReactiveCocoa 开发中常见的用法
    • 6-1 代替代理
    • 6-2 代替KVO
    • 6-3 监听事件
    • 6-4 代替通知
    • 6-5 监听文本框文字的改变
    • 6-6 处理多个请求 都返回结果的时候统一做处理
    • 6-7 定时器
    • 7 ReactiveCocoa 开发中常见的用法
    • 7-1 RAC(TARGET, ...) 用于给某个对象的某个属性绑定
    • 7-2 RACObserve(TARGET, KEYPATH) 监听某个对象的某个属性 返回的是信号
    • 7-3 RACTuplePack 把数据包装成RACTuple (元祖类) RACTupleUnpack 把元祖解包成对应的数据

    1 ReactiveCocoa 介绍

    ReactiveCocoa(其简称为RAC)是由Github 开源的一个应用于iOS和OS X开发的新框架。RAC具有函数式编程和响应式编程的特性

    2 ReactiveCocoa的应用场景

    对于一个应用来说,绝大部分的时间都是在等待某些事件的发生或响应某些状态的变化,比如用户的触摸事件、应用进入后台、网络请求成功刷新界面等等,而维护这些状态的变化,常常会使代码变得非常复杂,难以扩展。而 ReactiveCocoa 给出了一种非常好的解决方案,它使用信号来代表这些异步事件,提供了一种统一的方式来处理所有异步的行为,包括代理方法、block 回调、target-action 机制、通知、KVO 等

    3 ReactiveCocoa 被描述为函数式响应编程(FRP)框架

    ReactiveCocoa结合了几种编程风格

    函数式编程(Functional Programming)

    是把操作尽量写成一系列嵌套的函数或者方法调用。
    函数式编程特点:每个方法必须有返回值(本身对象),把函数或者Block当做参数,block参数(需要操作的值)block返回值(操作结果)

    代表: ReactiveCocoa

    响应式编程(Reactive Programming )

    不需要考虑调用顺序,只需要知道考虑结果,类似于蝴蝶效应,产生一个事件,会影响很多东西,这些事件像流一样的传播出去,然后影响结果,借用面向对象的一句话,万物皆是流。

    代表:KVO运用

    链式编程

    是将多个操作(多行代码)通过点号(.)链接在一起成为一句代码,使代码可读性好。a(1).b(2).c(3)

    链式编程特点:方法的返回值是block,block必须有返回值(本身对象),block参数(需要操作的值)

    代表作 Masonry

    4 添加ReactiveCocoa到项目中

    使用cocoapods 具体电脑配置cocoapods网上资料一大堆 我就不多说了 自行Google

    pod 'ReactiveCocoa', '~> 2.5'
    

    5 分析ReactiveCocoa的中的常见类

    仔细看了源码 发现 RAC中最核心的类是RACSignal, 好了 接下来就是研究RACSignal了

    5-1 RACSignal:信号类

    一般表示将来有数据传递 只要有数据改变信号内部接受到数据 就会马上发出数据

    注意:
    • RACSignal(信号类) 只是表示数据改变时 信号内部会发出数据 它本身不具备发送信号的能力 而是交给内部一个订阅者去发出(下文会讲到RACSubject类 有区别)

    • 默然信号都是冷信号 也就是值改变了也不会触发 只有订阅了这个信号 这个信号才是热信号 值改变了才会触发

    • 订阅信号:调用信号RACSignal的subscribeNext就能订阅

    RACSignal的简单使用:
       // 1 创建信号
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            
          
            // 2 发送信号
            [subscriber sendNext:@"123"];
            // 如果不发送数据 最好发送信号完成  内部会自动调用[RACDisposable disposable]取消订阅信号。
            [subscriber sendCompleted];
            
            return [RACDisposable disposableWithBlock:^{
                //block调用时刻:当信号发送完成或者发送错误,就会自动执行这个block,取消订阅信号。
                // 执行完Block后,当前信号就不在被订阅了。
                NSLog(@"信号被销毁了");
            }];
        }];
        
        // 3 订阅信号
        [signal subscribeNext:^(id x) {
            
    //        block 调用时刻 每当有信号发出数据 就会调用block;
            NSLog(@"接收到数据%@",x);
        }];
    
    • RACSignal的底层实现原理
      • 1.创建信号,首先把didSubscribe保存到信号中,还不会触发。
      • 2.当信号被订阅,也就是调用signal subscribeNext:nextBlock
      • 2.2 subscribeNext内部会创建订阅者subscriber,并且把nextBlock保存到subscriber中。
      • 2.1 subscribeNext内部会调用siganl的didSubscribe
      • 3.siganl的didSubscribe中调用[subscriber sendNext:@1];
      • 3.1 sendNext底层其实就是执行subscriber的nextBlock
    5-2 RACSubscriber

    表示订阅者的意思 用于发送信号 这是一个协议 不是一个类 只要遵守这个协议 并且实现方法才能成为订阅者 通过create创建的信号都有一个订阅者 帮助他发送数据

    5-3 RACDisposable

    用于取消订阅或者清理资源 当信号发送完成或者发送错误的时候 就会自动触发他

    • 不想监听某个信号时 可以通过它主动取消订阅信号
    5-4 RACSubject

    信号提供者 自己可以充当信号 又能发送信号

    • 通常用来代替代理 有了它 就不必要定义代理了

    RACReplySubject 重复提供信号类 ,RACSubject的子类

    • RACReplySubject 和RACSubject区别

    • RACReplySubject 可以先发送信号再订阅信号, RACSubject就不可以

    • 使用场景1 :如果一个信号每被订阅一次 就需要把之前的值重复发送一遍 使用重复提供信号类

    • 使用场景2 :可以设置capacity数量来限制缓存的value的数量 即只缓存最新的几个值

    RACSubject 的简单实用
    //    1 创建信号
        RACSubject *subject = [RACSubject subject];    
        // 2 订阅信号
        [subject subscribeNext:^(id x) {
            NSLog(@"第一个订阅者 %@",x);
        }];    
        [subject subscribeNext:^(id x) {
            NSLog(@"第二个订阅者  %@",x);
        }];
        // 3 发送信号
        [subject sendNext:@123];
        
    
    • RACSubject的底层实现原理
    • RACSubject底层实现 和RACSignal不一样
    • 1 调用SubjectNext 订阅信号 只是把订阅者保存起来 并且订阅者的nextBlock已经赋值了
    • 2 调用sendNext 发送信号遍历刚刚保存的订阅者 一个一个调用订阅者的nextBlock
    RACReplaySubject 的简单使用
        // 1 创建信号
        RACReplaySubject *replySubject = [RACReplaySubject subject];
        
        // 2 发送信号
        [replySubject sendNext:@"我是ReplySubject -- 1"];
        [replySubject sendNext:@"我是ReplySubject -- 2"];    
    
        // 3 订阅信号
        [replySubject subscribeNext:^(id x) {        
            NSLog(@"第一个订阅者接收到的数据%@",x);        
        }];
            
        [replySubject subscribeNext:^(id x) {       
            NSLog(@"第二个订阅者接收到的数据%@",x);    
        }];
        
    // 下边是打印结果
    第一个订阅者接收到的数据我是ReplySubject -- 1
    第一个订阅者接收到的数据我是ReplySubject -- 2
    第二个订阅者接收到的数据我是ReplySubject -- 1
    第二个订阅者接收到的数据我是ReplySubject -- 2
    
    • RACReplySubject的底层实现原理

      • RACReplaySubject:底层实现和RACSubject不一样。
      • 1.调用sendNext发送信号,把值保存起来,然后遍历刚刚保存的所有订阅者,一个一个调用订阅者的nextBlock。
      • 2.调用subscribeNext订阅信号,遍历保存的所有值,一个一个调用订阅者的nextBlock
      • 如果想当一个信号被订阅,就重复播放之前所有值,需要先发送信号,在订阅信号。 也就是先保存值,在订阅值。
    • RACSubject 的项目中的使用 替换代理
    // 在第一个控制器里边  我用的是脱线跳转 所有在此方法中获取控制器  实例化subject  然后订阅信号
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {    
        DetailViewController *detailVC = segue.destinationViewController;    
        // 实例化
        detailVC.delagateSignal = [RACSubject subject];    
        // 订阅信号
        [detailVC.delagateSignal subscribeNext:^(id x) {        
            NSLog(@"%@",x);        
        }];
    }
    
    //  在DetailViewController.h 中添加属性
    
    @property(nonatomic, strong)RACSubject *delagateSignal;
    
    // 在DetailViewController.m 中的点击方法中 判断 delagateSignal 是否实例话 然后发送信号
    - (IBAction)delegateBtn:(id)sender {    
        if (self.delagateSignal) {
            // 发送信号
            [self.delagateSignal sendNext:@"我是从详情里边出来的哈哈"];
        }
    }
    
    
    5-5 RACTuple:元祖类 类似NSArray 用来包装值
    5-6 RACSequence (Sequence:序列排序) :RAC中的集合类 用于代替NSArray 和 NSDictionary 可以使用它来快速遍历数组和字典
    • 简单使用 遍历数组 和遍历字典
    //     1 遍历数组
        NSArray *arr = @[@1,@2,@3,@4,@5];
        [arr.rac_sequence.signal subscribeNext:^(id x) {
            NSLog(@"%@",x);
        }];
    
    // 2 遍历字典
    
        // 2 遍历字典
        NSDictionary *dict = @{@"name":@"奥卡姆剃须刀",
                               @"age":@"25",
                               @"location":@"beijing"
                               };    
    
        [dict.rac_sequence.signal subscribeNext:^(id x) {       
            NSLog(@"%@",x);        
        }];
    此处打印出来的键值会被包装为RACTuple元祖类型  以下为打印结果
    Reactive Demo[9312:370525] <RACTuple: 0x608000004790> (
        location,
        beijing
    )
     
    //  所以遍历字典时候 应该将id直接改为RACTuple
    
        [dict.rac_sequence.signal subscribeNext:^(RACTuple * x) {        
            // 解包元祖 会把元祖的值 按顺序给参数里边的变量赋值
            RACTupleUnpack(NSString *key,NSString *value) = x;        
    
            NSLog(@"%@----%@",key,value);        
    
        }];
        
    // 打印结果 
     name----奥卡姆剃须刀
     age----25
     location----beijing
    
    • 实现字典转模型
    //     OC写法
        NSString *filePath = [[NSBundle mainBundle]pathForResource:@"PeopleList.plist" ofType:nil];    
        NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];    
        NSMutableArray *modelArr = [NSMutableArray arrayWithCapacity:dictArr.count];    
        for (NSDictionary *dict in dictArr) {        
            PeopleModel *model = [PeopleModel peopleWithDict:dict];
            [modelArr addObject:model];
        }
    
    // RAC 写法
        NSString *filePath = [[NSBundle mainBundle]pathForResource:@"PeopleList.plist" ofType:nil];    
        NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];    
        NSMutableArray *modelArr = [NSMutableArray arrayWithCapacity:dictArr.count];    
    // RACSequence 调用subcribeNext 并不会马上执行NextBlock 而是要等一会 可以在下方添加一个nslog  会现在log
        [dictArr.rac_sequence.signal subscribeNext:^(id x) {       
            PeopleModel *model = [PeopleModel peopleWithDict:x];        
            [modelArr addObject:model];
        }];
    NSLog(@"奥卡姆剃须刀");
    
    
    
        //  RAC高级写法    
        NSString *filePath = [[NSBundle mainBundle]pathForResource:@"PeopleList.plist" ofType:nil];    
        NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];
        NSArray *modelArr = [[dictArr.rac_sequence map:^id(id value) {        
            return [PeopleModel peopleWithDict:value];        
        }]array];    
        NSLog(@"%@",modelArr);
       
    // map: 映射的意思 把原始的值value映射成一个新值 形成一个新的集合 RACDynamicSequence 
    // array  把RACDynamicSequence集合准换成我们熟知的数组
    // 底层实现 当信号被订阅是 会遍历集合中的原始值  映射成新值 并且保存到新的RACDynamicSequence集合中
    
    
    5-7 RACCommand :RAC中用于处理事件的类, 可以吧事件如何处理,事件中的数据如何传递,包装到这个类中 他可以很方便的监控事件的执行过程
    • 监听按钮的点击,网络请求 简单实用
    
        // RACCommand使用步骤
        // 1 创建命令
        // 2 在signalBlock中 创建信号signal 作为signalblock的返回
        // 3 执行命令 execute
    
    
        // 1 创建命令
        RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
                          
            NSLog(@"执行命令%@",input);        
    
            // 2 创建信号  用来传递数据
            return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {        
                // 在这里边发送网络请求 然后将请求道的结果数据返回给外界                    
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{                
    
                    [subscriber sendNext:@"我是数据"];                
                    // 发送信号完成后 要发送完成
                    [subscriber sendCompleted];
                });                                  
                 
                return nil;
            }];
        }];    
        // 3 订阅RACCommand的信号 在此处可以拿到网络请求回来的数据
        [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(@"switchToLatest---%@",x);
            
        }];
        
        // 4 监听命令是否执行完毕  默认会来一次 可以直接跳过 skip表示跳过信号
        [[command.executing skip:1] subscribeNext:^(id x) {
        
            if ([x boolValue] == YES) {
                
                NSLog(@"正在执行");
                
            }else{
                
                NSLog(@"执行完毕");
            
            }
            
        }];
        
        // 5 执行命令 执行命令的时候 会调用command的block  订阅信号时  block中的信号才能发送出去
        [command execute:@1];
        
    
    • RACCommand 使用注意

      • 1 signalBlock 必须返回一个信号 不能返回nil 不过可以传一个空信号 [RACSignal empty];
      • 2 RACCommand 中信号如果数据传递完 必须调用 [subscriber sendCompleted];这是命令才会执行完毕 否则一直在执行过程中
      • 3 comman 需要强引用
    • RACCommand的设计思想 signalBlock内部为什么要返回一个信号 这个信号有什么用呢

      • 1 在RAC开发中 通常会把网络请求封装在RACCommand 直接执行某个command就能发送请求
      • 2 在RACCommand内部请求道数据的时候 需要把请求的数据传递给外界这时候就需要signalblock返回的信号传递了
    • 如何拿到command中返回信号发出的数据

      • 1 RACCommand 有一个执行信号源executionSignals 这个是signal of signals(信号的信号),意思是信号发出的数据是信号,不是普通的类型。
      • 2 订阅executionSignals 就能拿到RACCommand中返回的信号 然后订阅signalblock返回的信号 就能获取发出的值
    • 监听当前命令是否正在执行executing

    • 使用场景 监听按钮的点击 网络请求

    5-8 RACMulticastConnection 用于当一个信号被多次订阅是为了保证创建信号时 避免多次调用创建信号中的block 造成副作用 可以使用这个类创建
    • RACMulticastConnection 通过RACSignal 的publish或者muticast:方法创建
    // 来先看一个例子
        // 需求:假设在一个信号中发送请求,每次订阅一次都会发送请求,这样就会导致多次请求。
        // 解决:使用RACMulticastConnection就能解决.
    
    // 看一下错误的例子
    
        
        // 1 创建请求信号
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            NSLog(@"发送请求");
            [subscriber sendNext:@1];
            return nil;        
        }];    
        // 2 订阅信号
        [signal subscribeNext:^(id x) {       
            NSLog(@"接受数据1");        
        }];    
        // 3 再次订阅信号
        [signal subscribeNext:^(id x) {       
            NSLog(@"接收数据2");        
        }];    
        // 4 运行结果 会执行两遍发送请求  也就是每次订阅都会发送一次请求
        
    
    // 下边是使用RACMulticastConnection 能够解决发送两次请求的问题
    
    //    RACMulticastConnection 解决重复请求的问题
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {       
            NSLog(@"发送请求");
            [subscriber sendNext:@1];        
            return nil;
        }];        
        // 2 创建链接
        RACMulticastConnection *connect = [signal publish];    
        // 3 订阅信号    
        [connect.signal subscribeNext:^(id x) {
            NSLog(@"接受数据 1 --%@",x);
        }];    
        [connect.signal subscribeNext:^(id x) {       
            NSLog(@"接受数据 2 -- %@",x);        
        }];
        // 4 链接 激活信号
        [connect connect];
    
    • RACMulticastConnection底层原理:

    • 1.创建connect,connect.sourceSignal -> RACSignal(原始信号) connect.signal -> RACSubject

    • 2.订阅connect.signal,会调用RACSubject的subscribeNext,创建订阅者,而且把订阅者保存起来,不会执行block。

    • 3.[connect connect]内部会订阅RACSignal(原始信号),并且订阅者是RACSubject

    • 3.1.订阅原始信号,就会调用原始信号中的didSubscribe

    • 3.2 didSubscribe,拿到订阅者调用sendNext,其实是调用RACSubject的sendNext

    • 4.RACSubject的sendNext,会遍历RACSubject所有订阅者发送信号。

    • 4.1 因为刚刚第二步,都是在订阅RACSubject,因此会拿到第二步所有的订阅者,调用他们的nextBlock

    5-9 RACScheduler :RAC中的队列 用GCD封装的
    5-10 RACUnit :表示Stream不包含有意义的值 也就是看到这个 可以直接理解为nil

    6 ReactiveCocoa 开发中常见的用法

    6-1 代替代理
    • 个人感觉这个方法代替代理并没有省多少代码 类似于block 代码相对集中了而已
    
     // 代替代理    
    // 主控制器中的代码
        CustomView *V = [[CustomView alloc]initWithFrame:CGRectMake(100, 100, 200, 200)];
        V.backgroundColor = [UIColor redColor];
        [self.view addSubview:V];    
        V.delegate = self;
        
        [[V rac_signalForSelector:@selector(TapClick)] subscribeNext:^(id x) {
            NSLog(@"点击了视图中的按钮%@",x);
        }];
        
    // CustomView  中的代码 和之前遵守协议设置代理代理实现方法是一样一样的
    .h
    
    @protocol CustomViewDelagate <NSObject>
    
    - (void)CustomViewTapClick;
    
    @end
    
    @interface CustomView : UIView
    
    @property (nonatomic,weak) id<CustomViewDelagate> delegate;
    
    @end
    
    .m
    - (void)TapClick{
        if ([self.delegate respondsToSelector:@selector(CustomViewTapClick)]) {
            [self.delegate CustomViewTapClick];
        }
    }
    
    
    6-2 代替KVO
    • 使用RAC代替KVO很简单,一句话就可以搞定,而且相比传统的KVO,不仅代码不用放在一起写美观了很多,同时还能达到高聚合低耦合的目标
    //第一种方式   代替KVO
      [RACObserve(scrollView, contentOffset) subscribeNext:^(id x) {
          NSLog(@"%@",x);
      }];
    
    // 第二种方式
      // 2.KVO
        // 把监听redV的center属性改变转换成信号,只要值改变就会发送信号
        // observer:可以传入nil
        [[redV rac_valuesAndChangesForKeyPath:@"center" options:NSKeyValueObservingOptionNew observer:nil] subscribeNext:^(id x) {
            NSLog(@"%@",x);
        }];
    
    
    6-3 监听事件
    • rac_signalForControlEvents 同样简单,一句话搞定
        // 监听事件
        [[self.signalBtn rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(id x) {
            // 传递的btn
            NSLog(@"点击了按钮%@",x);        
        }];
    
    6-4 代替通知
       // 正确的写法--1  这个写法 当dealloc信号发出的时候 就释放通知
        [[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(id x) {        
            NSLog(@"键盘弹出");        
        }];
    
       // 正确的写法--2   自己创建一个要释放的信号
        RACSignal *deallocSignal = [self rac_signalForSelector:@selector(viewWillDisappear:)];    
        [[[[NSNotificationCenter defaultCenter]rac_addObserverForName:UIKeyboardWillShowNotification object:nil] takeUntil:deallocSignal] subscribeNext:^(id x) {
            NSLog(@"键盘弹出%@",x);
        }];
        
        // 这是个错误的示范  
    这个写法有个问题,这样子写信号不会被释放,当你再次收到键盘弹出的通知时他会叠加上次的信号进行执行,并一直叠加下去,所以我们在用上面的写法
      
        [[[NSNotificationCenter defaultCenter]rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {        
            NSLog(@"%@",x);        
        }];
    
    
    6-5 监听文本框文字的改变
     [self.textFiled.rac_textSignal subscribeNext:^(id x) {       
            NSLog(@"%@",x);
        }];
    
    
    6-6 处理多个请求 都返回结果的时候统一做处理
    - (void)moreRequest{    
    
        RACSignal *request1 = [RACSignal 
    createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {       
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{            
                [subscriber sendNext:@"我是数据 - 1"];
                [subscriber sendCompleted];
            });        
            return nil;
        }];
        
        RACSignal *request2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
           
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [subscriber sendNext:@"我是数据 - 2"];
                [subscriber sendCompleted];
            });
            return nil;
        }];
            
        // 前边的方法参数和后边信号的数据是一一对应的
        [self rac_liftSelector:@selector(reloadData1:Data2:) withSignalsFromArray:@[request1,request2]];    
    }
    // 接收到数据后在这里统一reloadData
    - (void)reloadData1:(id)Data1 Data2:(id)Data2{
        NSLog(@"ReloadData%@---%@",Data1,Data2);
    }
    
    
    6-7 定时器
    • 延时执行
        // 延时执行
        [[RACScheduler mainThreadScheduler] afterDelay:2 schedule:^{       
            NSLog(@"2秒后执行我");        
        }];
    
    • 定时执行
        // 定时执行  takeUntil 要条件限制一下 否则当控制器销毁后 还是会继续执行
        [[[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]]takeUntil:self.rac_willDeallocSignal] subscribeNext:^(id x) {
            NSLog(@"每隔1s会执行");
        }];
        
    

    7 ReactiveCocoa 开发中常见的宏

    7-1 RAC(TARGET, ...) 用于给某个对象的某个属性绑定
    RAC(self.label,text) = self.textFiled.rac_textSignal;
    
    7-2 RACObserve(TARGET, KEYPATH) 监听某个对象的某个属性 返回的是信号
        [RACObserve(self.textFiled,center ) subscribeNext:^(id x) {       
            NSLog(@"%@",x);        
        }];
        
    
    7-3 RACTuplePack 把数据包装成RACTuple (元祖类) RACTupleUnpack 把元祖解包成对应的数据
    
        // 把参数中的数据包装成元祖
        RACTuple *tuple = RACTuplePack(@10,@20,@30);
        
        // 要一一对应付
        RACTupleUnpack(NSString *name,NSString *name2,NSString *name3) = tuple;    
        NSLog(@"%@---%@---%@",name,name2,name3);
    
                                  本文章借鉴网络多篇文章 仅为学习笔记记录

    相关文章

      网友评论

        本文标题:ReactiveCocoa 个人学习笔记记录(一)

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