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

ReactiveCocoa 个人学习笔记记录(一)_第1张图片
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 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]  (
    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 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 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 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 

- (void)CustomViewTapClick;

@end

@interface CustomView : UIView

@property (nonatomic,weak) id 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 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 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 个人学习笔记记录(一))