iOS开发ReactiveCocoa(二):RACCommand篇


日照香炉生紫烟,遥看瀑布挂前川。
飞流直下三千尺,疑是银河落九天。

——李白《望庐山瀑布》

RACCommand 简单使用

  • RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程。
    • executionSignals是signal of signals,如果直接subscribe的话会得到一个signal,而不是我们想要的value,所以一般会配合switchToLatest。
    • errors : 跟正常的signal不一样,RACCommand的错误不是通过sendError来实现的,而是通过errors属性传递出来的。
    • executing 表示该command当前是否正在执行。

一、RACCommand使用步骤:

  • 创建命令 initWithSignalBlock:(RACSignal*(^)(id input))signalBlock
  • 在signalBlock中,创建RACSignal,并且作为signalBlock的返回值
  • 执行命令 - (RACSignal *)execute:(id)input

二、RACCommand使用注意:

  • signalBlock必须要返回一个信号,不能传nil.
  • 如果不想要传递信号,直接创建空的信号[RACSignal empty];
  • RACCommand中信号如果数据传递完,必须调用[subscriber sendCompleted],这时命令才会执行完毕,否则永远处于执行中。

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

  • 在RAC开发中,通常会把网络请求封装到RACCommand,直接执行某个RACCommand就能发送请求。
  • 当RACCommand内部请求到数据的时候,需要把请求的数据传递给外界,这时候就需要通过signalBlock返回的信号传递了。

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

  • RACCommand有个执行信号源executionSignals,这个是signal of signals(信号的信号),意思是信号发出的数据是信号,不是普通的类型。
  • 订阅executionSignals就能拿到RACCommand中返回的信号,然后订阅signalBlock返回的信号,就能获取发出的值。

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// 1.创建命
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
NSLog(@"执行命令");

// 创建空信号,必须返回信号
// return [RACSignal empty];

// 2.创建信号,用来传递数据
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"请求数据"];
// 注意:数据传递完,最好调用sendCompleted,这时命令才执行完毕。
[subscriber sendCompleted];
return nil;
}];
}];

// 强引用命令,不要被销毁,否则接收不到数据
_conmmand = command;

// 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(@"%@",x);
}];

// 4.监听命令是否执行完毕,默认会来一次,可以直接跳过,skip表示跳过第一次信号。
[[command.executing skip:1] subscribeNext:^(id x) {
if ([x boolValue] == YES) {
// 正在执行
NSLog(@"正在执行");
} else {
// 执行完成
NSLog(@"执行完成");
}
}];

// 5.执行命令
[self.conmmand execute:@1];
要不要鼓励一下😘