ReactiveCocoa(二)
阅读原文时间:2023年07月16日阅读:1

通过ReactiveCocoa(一)的学习,相信大家对ReactiveCocoa有了一些基本认识吧。下面就让我们来学习ReactiveCocoa的一些基本使用吧!

代替代理

在ReactiveCocoa(一)中讲到可以通过RACSubject代替代理,我们也可以通过rac_signalForSelector同样代替代理。

代码演练
// 需求:自定义redView,监听红色view中按钮点击
// 之前都是需要通过代理监听,给红色View添加一个代理属性,点击按钮的时候,通知代理做事情
// rac_signalForSelector:把调用某个对象的方法的信息转换成信号,就要调用这个方法,就会发送信号。
// 这里表示只要redV调用btnClick:,就会发出信号,订阅就好了。
[[redV rac_signalForSelector:@selector(btnClick:)] subscribeNext:^(id x) {
    NSLog(@"点击红色按钮");
}];

代替KVO

rac_valuesAndChangesForKeyPath:用于监听某个对象的某个属性发生变化。

代码演练
// 需求:每点击一次,年龄增加一次
// 定义一个age属性
- (void)obserVer {
    [[self rac_valuesForKeyPath:@"age" observer:nil] subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    self.age ++;
}

监听事件

rac_signalForControlEvents:用于监听某个事件。

代码演练
// 把按钮点击事件转化成信号,点击按钮,就会发送信号
[[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside]         subscribeNext:^(id x) {
        NSLog(@"监听按钮点击事件");
 }];

代替通知

rac_addObserverForName:用于监听某个通知。

代码演练
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
    NSLog(@"弹出键盘");
}];

监听文本框文字改变

rac_textSignal:用于监听文本框文字发生改变

代码演练
[[self.textField rac_textSignal] subscribeNext:^(id x) {
    NSLog(@"text:%@",x);
}];

处理当界面有多个请求时,需要都获取到数据,才能展示界面

rac_liftSelector:withSignalsFromArray:Signals:当传入的Signals(信号数组),每一个signal都至少sendNext过一次,就会去触发selector参数的方法。

注意:几个信号,参数一的方法就几个参数,每个参数对应信号发出的数据,否则运行时会报错。

代码演练
- (void)test{
    // 创建信号A
    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            NSLog(@"数据请求1");
            [subscriber sendNext:@"发送请求1回来的数据"];
            return [RACDisposable disposableWithBlock:^{
                NSLog(@"随便写写");
            }];
        }];

    // 创建信号B
    RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        NSLog(@"数据请求2");
        [subscriber sendNext:@"发送请求2回来的数据"];
        return nil;
    }];

    // RAC:就可以判断两个信号有没有都发出内容
    // SignalsFromArray:监听哪些信号的发出
    // 当signals数组中的所有信号都发送sendNext就会触发方法调用者(self)的selector
    // 注意:selector方法的参数不能乱写,有几个信号就对应几个参数
    // 不需要主动订阅signalA,signalB,方法内部会自动订阅
    [self rac_liftSelector:@selector(doneNextWithA:andB:) withSignalsFromArray:@[signalA,signalB]];
}

- (void)doneNextWithA:(NSString *)a andB:(NSString *)b {
     NSLog(@"请求完成,更新UI--a:%@,b:%@",a,b);
}

RAC(TARGET, …)

  • 用于给某个对象的某个属性绑定。

      // 只要文本框文字改变,就会修改label的文字
      RAC(self.labelView,text) = _textField.rac_textSignal;

RACObserve(TARGET,KEYPATH)

  • 监听某个对象的某个属性,返回的是信号

      [RACObserve(self, age) subscribeNext:^(id x) {
          NSLog(@"%@",x);
      }];

@weakify(Obj)和@strongify(Obj)

  • 一般都是成对出现,为了避免引起循环引用导致内存泄漏的,和block的使用类似。

      @weakify(self);
      [[_redView rac_signalForSelector:@selector(btnClick:)] subscribeNext:^(id x) {
      @strongify(self);
      NavViewController *navVC = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:NSStringFromClass([NavViewController class])];
      [self.navigationController pushViewController:navVC animated:YES];
      }];

RACTuplePack

  • 把数据包装成RACTuple(元组类)

    // 把参数中的数据包装成元组
    RACTuple *tuple = RACTuplePack(@"Scott_Mr",@20);

RACTupleUnpack

  • 把RACTuple(元组类)解包成对应的数据。

    // 解包元组,会把元组的值,按顺序给参数里面的变量赋值
    // name = @"Scott_Mr" age = @20
    RACTupleUnpack(NSString *name,NSNumber *age) = tuple;
    NSLog(@"%@,%@",name,age);

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan