RACCommand
2020-10-14 本文已影响0人
下班不写程序
文章系列
《ReactiveCocoa 概述》
《RACSignal》
《RACDisposable》
《RACSubject、RACReplaySubject(内附冷信号和热信号的区别)》
《集合RACTuple、RACSequence》
《RAC 中的通知、代理、KVO, 基本事件、方法的监听》
《rac_liftSelector》
《RACMulticastConnection》
《RACCommand》
《RAC - 核心方法bind》
《RAC - 定时器》
《RACScheduler》
《RAC - 点击获取验证码 demo》
《RAC - 映射(Map & flattenMap)》
《RAC信号操作解释合集》
《RAC - 信号的生命周期》
- 本质: 是一个用于管理 RACSignal 的创建与订阅的类.
- 使用场景:
网络请求或者代表着与交互(UI 交互)后即将执行的一段流程.
1. RACCommand 的初始化
- 通过
-initWithSignalBlock:方法初始化时都会传入一个类型为RACSignal * (^)(InputType _Nullable input)的signalBlock. - 注:
返回值不能为空
- (instancetype)initWithSignalBlock:(RACSignal<ValueType> * (^)(InputType _Nullable input))signalBlock;
- 通过
-initWithEnabled:方法初始化, 需要额外传递一个非空的enabledSignal信号.
- (instancetype)initWithEnabled:(nullable RACSignal<NSNumber *> *)enabledSignal signalBlock:(RACSignal<ValueType> * (^)(InputType _Nullable input))signalBlock;
2. RACCommand 的执行
- 注: 返回值是一个
RACSignal信号
- (RACSignal<ValueType> *)execute:(nullable InputType)input;
3. RACCommand 的属性
// 正在执行中的信号们, 是一个高阶信号
@property (nonatomic, strong, readonly) RACSignal<RACSignal<ValueType> *> *executionSignals;
// 订阅当前信号, 会获得bool 值, 来判断当前command 是否在执行
@property (nonatomic, strong, readonly) RACSignal<NSNumber *> *executing;
// 当前command是否能被执行
@property (nonatomic, strong, readonly) RACSignal<NSNumber *> *enabled;
// 表示我在command 运行过程中, 每一次出现的错误, 且需要使用subscribeNext: 来订阅
@property (nonatomic, strong, readonly) RACSignal<NSNumber *> *errors;
//允许并发执行, 默认值为NO
@property (atomic, assign) BOOL allowsConcurrentExecution;
4. RACCommand 的简单使用
- (void)RACCommandTest {
// 1. 创建命令 - initWithSignalBlock
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
NSLog(@"input:%@",input);
// 注意: 不能返回空的信号
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"input命令来了, 开始发送数据"];
return nil;
}];
}];
// 2. 执行命令
RACSignal *signal = [command execute:@"发送input 命令, 执行command"];
// 3. 订阅信号
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"数据: %@",x);
}];
}
打印结果:运行结果
- 测试属性
executionSignals
注 :executionSignals方法的订阅一定要放在execute之前, 否则没有作用.
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
NSLog(@"input:%@",input);
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"input命令来了, 开始发送数据"];
return nil;
}];
}];
// 先订阅
[command.executionSignals subscribeNext:^(id _Nullable x) {
NSLog(@"executionSignals: %@", x);
}];
// 再执行
[command execute:@"发送input 命令, 执行command"];
打印结果:executionSignals 订阅结果打印
通过switchToLatest 获取到高阶信号中最新发送的信号
// 高阶信号
RACSubject *advancedSignal = [RACSubject subject];
RACSubject *signal1 = [RACSubject subject];
RACSubject *signal2 = [RACSubject subject];
RACSubject *signal3 = [RACSubject subject];
[advancedSignal.switchToLatest subscribeNext:^(id _Nullable x) {
// 这里得到的就是最新一次的信号
NSLog(@"%@", x);
}];
[advancedSignal sendNext:signal1];
[advancedSignal sendNext:signal2];
[advancedSignal sendNext:signal3];
[signal1 sendNext:@"信号1"];
[signal2 sendNext:@"信号2"];
[signal3 sendNext:@"信号3"];
- 测试属性
executing
注:发送信号的最后界的要发送sendCompleted 或者sendError 以保证信号发送的终止
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
NSLog(@"input:%@",input);
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"input命令来了, 开始发送数据"];
// 需要告诉外界信号发送已经结束, 终止订阅
// 否则log日志将不会打印最后一行的'未执行'
[subscriber sendCompleted];
return nil;
}];
}];
[command.executionSignals.switchToLatest subscribeNext:^(id _Nullable x) {
NSLog(@"数据: %@",x);
}];
[command.executing subscribeNext:^(id _Nullable x) {
if ([x boolValue]){
NSLog(@"正在执行");
} else {
NSLog(@"未执行");
}
}];
[command execute:@"发送input 命令, 执行command"];
打印结果:executing监听结果
附:
- RACCommand UI相关demo可参考《RAC - 点击获取验证码 demo》
.End
运行结果
executionSignals 订阅结果打印
executing监听结果