一些基本概念
- RACCommand可以理解为“接收指令-分发任务-执行(execute)任务”
- 默认情况下,一个任务信号必须执行完毕或者执行失败,才能执行下一个任务,即sendCompleted或sendError
- 可以修改allowsConcurrentExecution属性,允许多任务同时执行
- RACCommand通常用在监听按钮点击、网络请求
RACCommand创建
//普通方式
- (id)initWithSignalBlock:(RACSignal * (^)(id input))signalBlock;
//绑定一个RACSignal,用来决定RACCommand是否可用
- (id)initWithEnabled:(RACSignal *)enabledSignal signalBlock:(RACSignal * (^)(id input))signalBlock;
简单模拟RACCommand和网络请求(并不一定是实际的做法)
typedef enum : NSUInteger
{
NetworkCommandLogin = 1001,
NetworkCommandRegister = 1002,
NetworkCommandLogout = 1003,
} NetworkCommand;
//1.创建command
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * (NSNumber *inputCommand) {
//实际应用的时候,这里写上网络请求,返回该网络请求对应的信号
//这样说会比较好理解:网络请求完成时候,信号sendCompleted或者sendError,然后RACCommand的订阅者收到该信号,执行后续操作
switch (inputCommand.unsignedIntegerValue)
{
case NetworkCommandLogin:
{
return [RACSignal createSignal:^RACDisposable *_Nullable (id < RACSubscriber > subscriber) {
NSLog(@"这是登录信号的block");
[subscriber sendNext:@"登录"];
[subscriber sendCompleted];
return nil;
}];
}
break;
case NetworkCommandRegister:
{
return [RACSignal createSignal:^RACDisposable *_Nullable (id < RACSubscriber > subscriber) {
NSLog(@"这是注册信号的block");
[subscriber sendNext:@"注册"];
[subscriber sendCompleted];
return nil;
}];
}
break;
case NetworkCommandLogout:
{
return [RACSignal createSignal:^RACDisposable *_Nullable (id < RACSubscriber > subscriber) {
NSLog(@"这是注销信号的block(模拟失败)");
[subscriber sendError:nil]; //这里模拟失败
return nil;
}];
}
break;
default:
return [RACSignal empty];
}
}];
//把这个属性设为YES,就能多任务同时执行
//command.allowsConcurrentExecution = YES;
//3.使用excuting来监听command进度
[[command.executing skip:1] subscribeNext:^(NSNumber *_Nullable x) {
if (x.boolValue)
{
NSLog(@"命令正在执行...");
}
else
{
NSLog(@"命令已经完成");
NSLog(@"-------------");
}
}];
//4.订阅RACCommand中的信号(信号源)
//4.1普通方式获取信号源
[command.executionSignals subscribeNext:^(id x) {
[x subscribeNext:^(id x) {
NSLog(@"普通方式获取的信号 收到信号 %@", x);
}];
}];
//4.2使用switchToLatest获取信号源
[command.executionSignals.switchToLatest subscribeNext:^(id _Nullable x) {
NSLog(@"switchToLatest获取的信号 收到信号 %@", x);
}];
//5.使用errors来订阅失败的讯号
[command.errors subscribeNext:^(NSError *_Nullable x) {
NSLog(@"command receive error : %@", x);
}];
//6.执行命令
[command execute:@(NetworkCommandLogin)]; //execute会返回一个RACSignal对象
//如果直接execute下一个命令,会报错:"The command is disabled and cannot be executed"
[command execute:@(NetworkCommandLogin)];
[command execute:@(NetworkCommandLogin)];
[command execute:@(NetworkCommandLogin)];
//直接看是看不到的,需要获取execute的RACSignal对象,订阅失败信息才能看到
RACSignal *failSignal = [command execute:@(NetworkCommandLogin)];
[failSignal subscribeError:^(NSError * _Nullable error) {
NSLog(@"错误信号:%@", error);
}];
//上一个命令需要等待下一个命令执行完毕,如果加一点延时,就能正确显示
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[command execute:@(NetworkCommandLogout)];
});
其他资料
ReactiveCocoa基本组件:理解和使用RACCommand
网友评论