RAC - ObjC

一、Reactive 之 ObjC 介绍

  • RAC - 响应式编程,帮我们简单粗暴地处理事件

  • RAC 是通过信号 处理事件的

  • RAC能满足我们一个需求,就是所有需求

创建信号 - 订阅信号 - 发送信号

RAC - ObjC_第1张图片
    // 创建信号必须先订阅
    // 订阅信号必须先发送

// 创建信号(冷信号)
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
    // 发送信号
    [subscriber sendNext:@"This is RAC"];
    
    return nil;
}];


// 订阅信号(热信号)
[signal subscribeNext:^(id  _Nullable x) {
    // x : 指的是信号本身的数据内容
    NSLog(@"x = %@", x);
}];    

取消订阅

// 1.信号发送完成
// 2.信号发送失败

// 订阅的取消取决于 `subscriber` 是否存在
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
    [subscriber sendNext:@"this is RAC"];
    self.subscriber = subscriber;
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"我取消了订阅");
    }];
}];
RACDisposable *disposable = [signal subscribeNext:^(id  _Nullable x) {
    NSLog(@"disposable - %@", x);
}];
[disposable dispose];

二、初步使用(demo)

  • KVO
    // KVO
    self.person = [[Person alloc] init];
    // 监听 person 的 name 属性
    [_RACObserve(self.person, name) subscribeNext:^(id  _Nullable x) {
        NSLog(@"name - %@", x);
    }];
    ```
    
* ######action target
// target
[[self.RACAcion rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
    NSLog(@"Click - RACAcion");
}];

* ######通知

// 通知, 监听键盘弹出通知
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidChangeFrameNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
NSLog(@"motification - %@", x);
}];
```

  • 文本框代理
// 充当textView的代理
    [[self.RACTextView rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"textView - %@", x);
    }];
  • touchesBegin 辅助
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // KVO
    // 在这里改变name的值
    self.person.name = [NSString stringWithFormat:@"ThinkDifferent%u", arc4random_uniform(10000)];
    
    // 通知 - 退下键盘
    [self.view endEditing:true];
}

三、进阶使用

界面有多个网络请求, 当所有网络请求都完成时, 才能展示界面.

- (void)viewDidLoad {
    [super viewDidLoad];

    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id subscriber) {
        // requestA()
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            [NSThread sleepForTimeInterval:3.0];
            [subscriber sendNext:@"网络A加载完成"];
        });
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"取消A信号");
        }];
    }];
    RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id subscriber) {
        // requestB()
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            [NSThread sleepForTimeInterval:5.0];
            [subscriber sendNext:@"网络B加载完成"];
        });
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"取消B信号");
        }];
    }];

    [self rac_liftSelector:@selector(responseA:B:) withSignalsFromArray:@[signalA, signalB]];

}

- (void)responseA:(id)a B:(id)b {
    NSLog(@"%@, %@", a, b);
}

当一个界面有多个UITextField和UIButton选项,只有所有的UITextField都有值时UIButton才能可以点击。

- (void)viewDidLoad {
    [super viewDidLoad];

    [self rac_liftSelector:@selector(responseA:B:) withSignalsFromArray:@[self.textField1.rac_textSignal, self.textField2.rac_textSignal]];

}

- (void)responseA:(NSString *)str1 B:(NSString *)str2 {
    if(![str1 isEqualToString:@""] && ![str2 isEqualToString:@""]) {
        self.btn.enabled = YES;
    } else {
        self.btn.enabled = NO;
    }
}

四、应用

发送短信验证码Demo - textView拖动不会影响Timer

五、资源

附上唐大师博客

你可能感兴趣的:(RAC - ObjC)