reactiveCocoa实践二

  . 信号类 : 表示有数据产生

*    RACSignal

*    RACDynamicSignal  -> didSubscribe(block)

*    RACSubject  -> subscribers( 数组 )

*    RACReplaySubject  -> valuesReceived( 数组 )


 .不同的信号订阅方式不同

*    RACDynamicSignal  :
* 1. 创建订阅者 RACSubscriber
* 2.
执行 didSubscribe

*    RACSubject  :
* 1. 创建订阅者 RACSubscriber
* 2.
保存订阅者

*    RACReplaySubject  :
* 1. 创建订阅者 RACSubscriber
* 2.
拿到当前创建订阅者 , 发送之前保存的所有值

 .订阅者:发送数据

*    RACSubscriber  -> nextBlock(block)

*    RACSubject  -> subscribers( 数组 )

*    RACReplaySubject  -> valuesReceived( 数组 )

 .不同订阅者,发送数据方式不同

* [ RACSubscriber  sendNext] :
* 执行 nextBlock

* [ RACSubject  sendNext] :
* 遍历自己所有订阅者 , 发送数据

* [ RACReplaySubject  sendNext] :
* 1. 保存发送的值
* 2. 遍历自己所有订阅者 , 发送数据


常用宏
- ( void )RAC
{
   
// 监听文本框内容
   
//    [_textField.rac_textSignal subscribeNext:^(id x) {
   
//
   
//        _label.text = x;
   
//    }];
   
   
// 用来给某个对象的某个属性绑定信号 , 只要产生信号内容 , 就会把内容给属性赋值
    RAC(_label,text) = _textField.rac_textSignal;
}


// 只要这个对象的属性一改变就会产生信号
    [RACObserve(
self .view, frame) subscribeNext:^( id x) {
        NSLog(
@"%@" ,x);
    }];

等同于
  [[ self .view rac_valuesForKeyPath:@"frame" observer:nil] subscribeNext:^(id x) {
      // x: 修改的值  
        NSLog( @"%@" ,x);
    }];


  // 包装元组
    RACTuple *tuple = RACTuplePack(@1,@2);
   
    NSLog(@"%@",tuple[0]);  



//弱引用(避免造成循环引用)
  @weakify( self );
   
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(
id <RACSubscriber> subscriber) {
      
        @strongify(
self )
       
        NSLog(
@"%@" , self );
       
       
return nil ;
    }];
    _signal = signal;




RACMulticastConnection
  每次订阅不要都请求一次,指向请求一次,每次订阅只要拿到数据
   
   
// 不管订阅多少次信号 , 就会请求一次
   
// RACMulticastConnection: 必须要有信号
   
   
// 1. 创建信号
   
// 2. 把信号转换成连接类
   
// 3. 订阅连接类的信号
    // 4. 连接

- ( void )subject
{
    RACSubject *subject = [RACSubject subject];
   
    [subject subscribeNext:^(
id x) {
       
        NSLog(
@"1:%@" ,x);
       
    }];
    [subject subscribeNext:^(
id x) {
       
        NSLog(
@"2:%@" ,x);
       
    }];
   
    [subject sendNext:
@1 ];
}

- ( void )connect1
{
   
   
// 1. 创建信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(
id <RACSubscriber> subscriber) {
       
// didSubscribe 什么时候来 : 连接类连接的时候
        NSLog(
@" 发送热门模块的请求 " );
        [subscriber sendNext:
@" 热门模块的数据 " ];
       
       
return nil ;
    }];
   
// 2. 把信号转换成连接类
   
// 确定源信号的订阅者 RACSubject
   
   
// 先订阅再发送
   
//RACMulticastConnection *connection = [signal publish];
   
// 先发送再订阅
    RACMulticastConnection *connection = [signal multicast:[RACReplaySubject subject]];
   
   
// 3. 订阅连接类信号
    [connection.signal subscribeNext:^(
id x) {
       
       
// nextBlock: 发送数据就会来
        NSLog(
@" 订阅者 1:%@" ,x);
       
    }];
   
   
// 4. 连接
    [connection connect];

}

- ( void )requestBug
{
   
// 1. 创建信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(
id <RACSubscriber> subscriber) {
       
        NSLog(
@" 发送热门模块的请求 " );
       
       
// 3. 发送数据
        [subscriber sendNext:
@1 ];
       
       
return nil ;
    }];
   
   
// 2. 订阅信号
    [signal subscribeNext:^(
id x) {
        NSLog(
@" 订阅者一 %@" ,x);
    }];
   
    [signal subscribeNext:^(
id x) {
       
        NSLog(
@" 订阅者二 %@" ,x);
    }];

}








RACCommand
1. 方式一:直接订阅执行命令返回的信号(先发送信号,再订阅)
- ( void )command
{
   
// RACCommand: 处理事件
   
// RACCommand: 不能返回一个空的信号
   
// 1. 创建命令
    RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(
id input) {
       
// input: 执行命令传入参数
       
// Block 调用 : 执行命令的时候就会调用
        NSLog(
@"%@" ,input);
       
       
return [RACSignal createSignal:^RACDisposable *( id <RACSubscriber> subscriber) {
           
           
// 发送数据
            [subscriber sendNext:
@" 执行命令产生的数据 " ];
           
           
return nil ;
        }];
    }];
   
   
// 如何拿到执行命令中产生的数据
   
// 订阅命令内部的信号
   
   
   
   
// 2. 执行命令
    RACSignal *signal = [command execute:@1];
   
   
// 3. 订阅信号
    [signal subscribeNext:^(
id x) {
        NSLog(
@"%@" ,x);
    }];

}


2. 方式二:拿到正在执行的信号 RACSignal ,订阅正在执行的信号(先订阅,再发送信号)
- ( void )executionSignals
{
   
// 1. 创建命令
    RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(
id input) {
       
// input: 执行命令传入参数
       
// Block 调用 : 执行命令的时候就会调用
        NSLog(
@"%@" ,input);
       
       
return [RACSignal createSignal:^RACDisposable *( id <RACSubscriber> subscriber) {
           
           
// 发送数据
            [subscriber sendNext:
@" 执行命令产生的数据 " ];
           
           
return nil ;
        }];
    }];
   
   
// 订阅信号
   
// 注意 : 必须要在执行命令前 , 订阅
   
// executionSignals: 信号源 , 信号中信号 ,signalOfSignals: 信号 : 发送数据就是信号
   
// 拿到执行中的信号
   
//    [command.executionSignals subscribeNext:^(RACSignal *x) {
   
//
   
//        [x subscribeNext:^(id x) {
   
//            NSLog(@"%@",x);
   
//        }];
   
//
   
//    }];
   
   
// switchToLatest 获取最新发送的信号 , 只能用于信号中信号
    [command.executionSignals.switchToLatest subscribeNext:^(
id x) {
        NSLog(
@"%@" ,x);
    }];
   
   
// 2. 执行命令
    [command execute:@1];
}



3. switchToLatest  获取信号中信号发送的最新信号
- ( void )switchToLatest
{
   
   
// 创建信号中信号
    RACSubject *signalOfSignals = [RACSubject subject];
    RACSubject *signalA = [RACSubject subject];
    RACSubject *signalB = [RACSubject subject];
   
   
// 订阅信号
   
//    [signalOfSignals subscribeNext:^(RACSignal *x) {
   
//        [x subscribeNext:^(id x) {
   
//            NSLog(@"%@",x);
   
//        }];
   
//    }];
   
// switchToLatest: 获取信号中信号发送的最新信号
    [signalOfSignals.switchToLatest subscribeNext:^(
id x) {
       
        NSLog(
@"%@" ,x);
    }];
   
   
// 发送信号
    [signalOfSignals sendNext:signalA];
   
    [signalA sendNext:@1];
    [signalB sendNext:
@"BB" ];
    [signalA sendNext:
@"11" ];
}



4.监听事件有没有完成
  // 当前命令内部发送数据完成 , 一定要主动发送完成
   
// 1. 创建命令
    RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(
id input) {
       
// input: 执行命令传入参数
       
// Block 调用 : 执行命令的时候就会调用
        NSLog(
@"%@" ,inpu7t);
       
       
return [RACSignal createSignal:^RACDisposable *( id <RACSubscriber> subscriber) {
           
           
// 发送数据
            [subscriber sendNext:
@" 执行命令产生的数据 " ];
           
           
// 发送完成
            [subscriber sendCompleted];
           
           
return nil ;
        }];
    }];
   
   
// 监听事件有没有完成
    [command.executing subscribeNext:^(
id x) {
       
if ([x boolValue] == YES ) { // 当前正在执行
            NSLog(
@" 当前正在执行 " );
        }
else {
           
// 执行完成 / 没有执行
            NSLog(
@" 执行完成 / 没有执行 " );
        }
    }];
 
   
   
// 2. 执行命令
    [command execute:@1];




绑定信号(将发送的信号拦截进行一些操作)
#import "RACReturnSignal.h"
  // 1. 创建信号
    RACSubject *subject = [RACSubject subject];
   
   
// 2. 绑定信号
    RACSignal *bindSignal = [subject bind:^RACStreamBindBlock{
       
// block 调用时刻 : 只要绑定信号被订阅就会调用
       
       
       
return ^RACSignal *( id value, BOOL *stop){
           
// block 调用 : 只要源信号发送数据 , 就会调用 block
           
// block 作用 : 处理源信号内容
           
// value: 源信号发送的内容
           
            NSLog(
@" 接收到原信号的内容 :%@" ,value);
           
            value = [NSString stringWithFormat:
@"xmg:%@" ,value];
           
// 返回信号 , 不能传 nil, 返回空信号 [RACSignal empty]
           
return [RACReturnSignal return :value];
        };
    }];
   
   
// 3. 订阅绑定信号
    [bindSignal subscribeNext:^(
id x) {
      
// blcok: 当处理完信号发送数据的时候 , 就会调用这个 Block
        NSLog(
@" 接收到绑定信号处理完的信号 %@" ,x);
    }];
   
   
// 4. 发送数据
    [subject sendNext:@"123"];




映射
- ( void )flattenMap
{
   
// 创建信号
    RACSubject *subject = [RACSubject subject];
   
   
// 绑定信号
    RACSignal *bindSignal = [subject flattenMap:^RACStream *(
id value) {
       
// block: 只要源信号发送内容就会调用
       
// value: 就是源信号发送内容
       
        value = [NSString stringWithFormat:
@"xmg:%@" ,value];
       
       
// 返回信号用来包装成修改内容值
       
return [RACReturnSignal return :value];
       
    }];
   
   flattenMap 中返回的是什么信号,订阅的就是什么信号
   
   
// 订阅信号
    [bindSignal subscribeNext:^(
id x) {
       
        NSLog(
@"%@" ,x);
    }];
   
   
   
// 发送数据
    [subject sendNext:
@"123" ];
}






- ( void )map
{
   
// @"123"
   
// @"xmg:123"
   
   
// 创建信号
    RACSubject *subject = [RACSubject subject];
   
   
// 绑定信号
    RACSignal *bindSignal = [subject map:^id(id value) {
         map返回的类型,就是你需要映射的值
        return [NSString stringWithFormat: @"xmg:%@" ,value];
       
    }];
   
   
// 订阅绑定信号
    [bindSignal subscribeNext:^(
id x) {
       
        NSLog(
@"%@" ,x);
    }];
   
    [subject sendNext:
@"123" ];
    [subject sendNext:
@"321" ];
}



 

 Map flatternMap 的区别 :
1.FlatternMap 中的 Block 返回信号。
2.Map 中的 Block 返回对象。
3. 开发中,如果信号发出的值不是信号,映射一般使用 Map
4. 开发中,如果信号发出的值是信号,映射一般使用 FlatternMap



flattenMap: 用于信号中信号
 
    RACSubject *signalOfsignals = [RACSubject subject];
   
    RACSubject *signal = [RACSubject subject];
   
   

// 订阅信号中的信号 (3种) 方法一 :
//    [signalOfsignals subscribeNext:^(RACSignal *x) {
//       
//        [x subscribeNext:^(id x) {
//            NSLog(@"%@",x);
//        }];
//       
//    }];
    


方法二:
//    RACSignal *bindSignal = [signalOfsignals flattenMap:^RACStream *(id value) {
//        // value: 源信号发送内容
//        return value;
//    }];
//   
//    [bindSignal subscribeNext:^(id x) {
//       
//        NSLog(@"%@",x);
//    }];
    [[signalOfsignals flattenMap:^RACStream *(
id value) {
       
return value;
       
    }] subscribeNext:^(
id x) {
       
        NSLog(
@"%@" ,x);
       
    }];
   
   
// 发送信号
    [signalOfsignals sendNext:signal];
    [signal sendNext:@"213"];


方法三: switchToLatest 








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值