ReactiveCocoa之RACCommand使用(五)

1.RACCommand:RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程。

2.使用场景:监听按钮点击,网络请求


RACCommand的简单使用

     一、RACCommand使用步骤:

     1.创建命令 initWithSignalBlock:(RACSignal * (^)(id input))signalBlock

     2.signalBlock中,创建RACSignal,并且作为signalBlock的返回值

     3.执行命令 - (RACSignal *)execute:(id)input

    

     二、RACCommand使用注意:

     1.signalBlock必须要返回一个信号,不能传nil.

     2.如果不想要传递信号,直接创建空的信号[RACSignal empty];

     3.RACCommand中信号如果数据传递完,必须调用[subscriber sendCompleted],这时命令才会执行完毕,否则永远处于执行中。

     4.RACCommand需要被强引用,否则接收不到RACCommand中的信号,因此RACCommand中的信号是延迟发送的。

    

     三、RACCommand设计思想:内部signalBlock为什么要返回一个信号,这个信号有什么用。

     1.RAC开发中,通常会把网络请求封装到RACCommand,直接执行某个RACCommand就能发送请求。

     2.RACCommand内部请求到数据的时候,需要把请求的数据传递给外界,这时候就需要通过signalBlock返回的信号传递了。

    

     四、如何拿到RACCommand中返回信号发出的数据。

     1.RACCommand有个执行信号源executionSignals,这个是signal of signals(信号的信号),意思是信号发出的数据是信号,不是普通的类型。

     2.订阅executionSignals就能拿到RACCommand中返回的信号,然后订阅signalBlock返回的信号,就能获取发出的值。

    

     五、监听当前命令是否正在执行executing

    

     六、使用场景,监听按钮点击,网络请求

[objc]  view plain  copy
  1. // 普通做法  
  2. - (void)test1 {  
  3.     // RACCommand: 处理事件  
  4.     // 不能返回空的信号  
  5.     // 1.创建命令  
  6.     RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {  
  7.         //block调用,执行命令的时候就会调用  
  8.         NSLog(@"%@",input); // input 为执行命令传进来的参数  
  9.         // 这里的返回值不允许为nil  
  10.         return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {  
  11.             [subscriber sendNext:@"执行命令产生的数据"];  
  12.             return nil;  
  13.         }];  
  14.     }];  
  15.       
  16.     // 如何拿到执行命令中产生的数据呢?  
  17.     // 订阅命令内部的信号  
  18.     // ** 方式一:直接订阅执行命令返回的信号  
  19.       
  20.     // 2.执行命令  
  21.     RACSignal *signal =[command execute:@2]; // 这里其实用到的是replaySubject 可以先发送命令再订阅  
  22.     // 在这里就可以订阅信号了  
  23.     [signal subscribeNext:^(id x) {  
  24.         NSLog(@"%@",x);  
  25.     }];  
  26.       
  27. }  
  28. // 一般做法  
  29. - (void)test2 {  
  30.     // 1.创建命令  
  31.     RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {  
  32.         //block调用,执行命令的时候就会调用  
  33.         NSLog(@"%@",input); // input 为执行命令传进来的参数  
  34.         // 这里的返回值不允许为nil  
  35.         return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {  
  36.             [subscriber sendNext:@"执行命令产生的数据"];  
  37.             return nil;  
  38.         }];  
  39.     }];  
  40.       
  41.     // 方式二:  
  42.     // 订阅信号  
  43.     // 注意:这里必须是先订阅才能发送命令  
  44.     // executionSignals:信号源,信号中信号,signalofsignals:信号,发送数据就是信号  
  45.     [command.executionSignals subscribeNext:^(RACSignal *x) {  
  46.         [x subscribeNext:^(id x) {  
  47.             NSLog(@"%@", x);  
  48.         }];  
  49. //        NSLog(@"%@", x);  
  50.     }];  
  51.       
  52.     // 2.执行命令  
  53.     [command execute:@2];  
  54. }  
  55. // 高级做法  
  56. - (void)test3 {  
  57.       
  58.     // 1.创建命令  
  59.     RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {  
  60.         // block调用:执行命令的时候就会调用  
  61.         NSLog(@"%@", input);  
  62.         // 这里的返回值不允许为nil  
  63.         return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {  
  64.             [subscriber sendNext:@"发送信号"];  
  65.             return nil;  
  66.         }];  
  67.     }];  
  68.       
  69.     // 方式三  
  70.     // switchToLatest获取最新发送的信号,只能用于信号中信号。  
  71.     [command.executionSignals.switchToLatest subscribeNext:^(id x) {  
  72.         NSLog(@"%@", x);  
  73.     }];  
  74.     // 2.执行命令  
  75.     [command execute:@3];  
  76.       
  77. }  
  78.   
  79. // switchToLatest  
  80. - (void)test4 {  
  81.     // 创建信号中信号  
  82.     RACSubject *signalofsignals = [RACSubject subject];  
  83.     RACSubject *signalA = [RACSubject subject];  
  84.      // 订阅信号  
  85. //    [signalofsignals subscribeNext:^(RACSignal *x) {  
  86. //        [x subscribeNext:^(id x) {  
  87. //            NSLog(@"%@", x);  
  88. //        }];  
  89. //    }];  
  90.     // switchToLatest: 获取信号中信号发送的最新信号  
  91.     [signalofsignals.switchToLatest subscribeNext:^(id x) {  
  92.         NSLog(@"%@", x);  
  93.     }];  
  94.     // 发送信号  
  95.     [signalofsignals sendNext:signalA];  
  96.     [signalA sendNext:@4];  
  97. }  
  98.   
  99. /* 
  100.  RACCommand 通常用来表示某个Action的执行,比如点击Button。它有几个比较重要的属性:executionSignals / errors / executing。 
  101.   
  102.  1、executionSignals是signal of signals,如果直接subscribe的话会得到一个signal,而不是我们想要的value,所以一般会配合switchToLatest。 
  103.   
  104.  2、errors。跟正常的signal不一样,RACCommand的错误不是通过sendError来实现的,而是通过errors属性传递出来的。 
  105.   
  106.  3、executing表示该command当前是否正在执行。 
  107.  */  
  108.   
  109.   
  110. // 监听事件有没有完成  
  111. - (void)test5 {  
  112.     //注意:当前命令内部发送数据完成,一定要主动发送完成  
  113.     // 1.创建命令  
  114.     RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {  
  115.         // block调用:执行命令的时候就会调用  
  116.         NSLog(@"%@", input);  
  117.         // 这里的返回值不允许为nil  
  118.         return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {  
  119.             // 发送数据  
  120.             [subscriber sendNext:@"执行命令产生的数据"];  
  121.               
  122.             // *** 发送完成 **  
  123.             [subscriber sendCompleted];  
  124.             return nil;  
  125.         }];  
  126.     }];  
  127.     // 监听事件有没有完成  
  128.     [command.executing subscribeNext:^(id x) {  
  129.         if ([x boolValue] == YES) { // 正在执行  
  130.             NSLog(@"当前正在执行%@", x);  
  131.         }else {  
  132.             // 执行完成/没有执行  
  133.             NSLog(@"执行完成/没有执行");  
  134.         }  
  135.     }];  
  136.       
  137.     // 2.执行命令  
  138.     [command execute:@1];  
  139.       
  140. }  
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值