RACCommand

文章系列
《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 * (^)(InputType _Nullable input))signalBlock;
  • 通过 -initWithEnabled: 方法初始化, 需要额外传递一个非空的enabledSignal信号.
- (instancetype)initWithEnabled:(nullable RACSignal *)enabledSignal signalBlock:(RACSignal * (^)(InputType _Nullable input))signalBlock;

2. RACCommand 的执行

  • 注: 返回值是一个RACSignal 信号
- (RACSignal *)execute:(nullable InputType)input;

3. RACCommand 的属性

// 正在执行中的信号们, 是一个高阶信号
@property (nonatomic, strong, readonly) RACSignal *> *executionSignals;

// 订阅当前信号, 会获得bool 值, 来判断当前command 是否在执行
@property (nonatomic, strong, readonly) RACSignal *executing;

// 当前command是否能被执行
@property (nonatomic, strong, readonly) RACSignal *enabled;

// 表示我在command 运行过程中, 每一次出现的错误, 且需要使用subscribeNext: 来订阅
@property (nonatomic, strong, readonly) RACSignal *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  _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  _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  _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

你可能感兴趣的:(RACCommand)