美文网首页
iOS开发-关于ReactiveCocoa的知识点(一)

iOS开发-关于ReactiveCocoa的知识点(一)

作者: 看我的大白眼 | 来源:发表于2018-02-06 09:03 被阅读26次

1:RACSignal基础知识点

信号类(RACSignal),只是表示当数据改变时,信号内部会发出数据,它本身不具备发送信号的能力,而是交给内部一个订阅者去发出。
默认一个信号都是冷信号,也就是值改变了,也不会触发,只有订阅了这个信号,这个信号才会变为热信号,值改变了才会触发。
如何订阅信号:调用信号RACSignal的subscribeNext就能订阅

补充:

ReactiveCocoa signal(RACSignal)发送事件流给它的subscriber。目前总共有三种类型的事件:next、error、completed。一个signal在因error终止或者完成前,可以发送任意数量的next事件

ReactiveCocoa框架使用category来为很多基本UIKit控件添加signal。这样你就能给控件添加订阅了!

举例:用户登录操作

账号和密码

UITextField *userNameTextField;

    [self.userNameTextField.rac_textSignal subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"%@",x);
    }];

console的输出

2018-02-05 11:27:48.604420+0800 RACTest[13247:938527] 我们
2018-02-05 11:27:49.600529+0800 RACTest[13247:938527] 我们一起
2018-02-05 11:27:50.315228+0800 RACTest[13247:938527] 我们一起努力

可以看到每次改变文本框中的文字,block中的代码都会执行。没有target-action,没有delegate,只有signal和block。

  • 用到的操作方法:

  • filter:过滤信号,使用它可以获取满足条件的信号.

    [[self.userNameTextField.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
        return value.length > 3;
    }] subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"%@",x);
    }];

console的输出,只有当输入超过3个字符时才会有log

2018-02-05 11:31:48.369001+0800 RACTest[13268:940054] 我们一起
2018-02-05 11:31:49.801313+0800 RACTest[13268:940054] 我们一起努力

用图形来表达就是下面这样的:

filter

从上面的图中可以看到,rac_textSignal是起始事件。然后数据通过一个filter,如果这个事件包含一个长度超过3的字符串,那么该事件就可以通过。管道的最后一步就是subscribeNext:,block在这里打印出事件的值

RACSignal的每个操作都会返回一个RACsignal,这在术语上叫做连贯接口(fluent interface)。这个功能可以让你直接构建管道,而不用每一步都使用本地变量

    RACSignal *usernameSourceSignal = self.userNameTextField.rac_textSignal;
    
    RACSignal *filteredUsername = [usernameSourceSignal filter:^BOOL(id  _Nullable value) {
        NSString *text = value;
        return text.length > 3;
    }];
    
    [filteredUsername subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
  • flattenMap map 用于把源信号内容映射成新的内容
    [[[self.userNameTextField.rac_textSignal map:^id _Nullable(NSString * _Nullable value) {
        return @(value.length);
    }] filter:^BOOL(id  _Nullable value) {
        return [value integerValue] > 3;
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];

console的输出

2018-02-05 13:18:43.982224+0800 RACTest[13730:968563] 4
2018-02-05 13:18:44.696426+0800 RACTest[13730:968563] 6
2018-02-05 13:18:46.186301+0800 RACTest[13730:968563] 7

新加的map操作通过block改变了事件的数据。map从上一个next事件接收数据,通过执行block把返回值传给下一个next事件。在上面的代码中,map以NSString为输入,取字符串的长度,返回一个NSNumber

image
  • 用到的宏定义运用

    • RAC(TARGET, [KEYPATH, [NIL_VALUE]]):用于给某个对象的某个属性绑定
    RACSignal *validUsernameSignal = [self.userNameTextField.rac_textSignal map:^id _Nullable(NSString * _Nullable value) {
        return @(value.length > 3);
    }];
    
    [[validUsernameSignal map:^id _Nullable(NSNumber *value) {
        return [value boolValue] ? [UIColor clearColor] : [UIColor redColor];
    }] subscribeNext:^(UIColor *color) {
        self.passwordTextField.backgroundColor = color;
    }];
    
    // 用于给某个对象的某个属性绑定
    RAC(self.userNameTextField,backgroundColor) = [validUsernameSignal map:^id _Nullable(NSNumber *value) {
        return [value boolValue] ? [UIColor clearColor] : [UIColor yellowColor];
    }];
    
    
    

    注释:

    现在的逻辑用图形来表示就是下面这样的。能看到有两条简单的管道,两个文本信号,经过一个map转为表示是否有效的布尔值,再经过一个map转为UIColor,而这个UIColor已经和输入框的背景颜色绑定了。

    map

登录操作

  • combineLatest:将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的signal至少都有过一次sendNext,才会触发合并的信号。
    RACSignal *signUpActiveSignal = [RACSignal combineLatest:@[validUsernameSignal,validPasswordSignal] reduce:^id (NSNumber *usernameValid, NSNumber *passwordValid){
        
        return @([usernameValid boolValue] && [passwordValid boolValue]);
    }];

上面的代码使用combineLatest:reduce:方法把validUsernameSignal和validPasswordSignal产生的最新的值聚合在一起,并生成一个新的信号。每次这两个源信号的任何一个产生新值时,reduce block都会执行,block的返回值会发给下一个信号。

把信号和按钮的enabled属性绑定。

    [signInActiveSignal subscribeNext:^(id  _Nullable x) {
        self.signInButton.enabled = [x boolValue];
    }];

登录流程

login

上图展示了一些重要的概念,你可以使用ReactiveCocoa来完成一些重量级的任务。

分割—信号可以有很多subscriber,也就是作为很多后续步骤的源。注意上图中那个用来表示用户名和密码有效性的布尔信号,它被分割成多个,用于不同的地方。

聚合—多个信号可以聚合成一个新的信号,在上面的例子中,两个布尔信号聚合成了一个。实际上你可以聚合并产生任何类型的信号。

按钮点击事件

    [[self.signInButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
       NSLog(@"signInButton click");
   }];

参考博客

ReactiveCocoa入门教程:第一部分
ReactiveCocoa的知识点及MVVM模式运用(不断更新中....)

相关文章

网友评论

      本文标题:iOS开发-关于ReactiveCocoa的知识点(一)

      本文链接:https://www.haomeiwen.com/subject/jwiwzxtx.html