ReactiveObjC 基本使用总结

本篇博客主要分析RAC 的基本使用 关于原理部分这里不再写,后边分析源码时会将相应的分析体会再做整理

信号产生 订阅 发送
形式 1
- (void)testSignalSend{
    // 创建
    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        // 发送
        [subscriber sendNext:@"数据来了"];
        [subscriber sendCompleted];
        return [RACDisposable disposableWithBlock:^{
            
        }];
    }];
    // 订阅
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"---testSignalSend-----%@", x);
    }];
    
}
形式 2
- (void)testRACSubject{
    RACSubject *subject = [RACSubject subject];
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"-------%@", x);
    }];
    [subject sendNext:@"数据来了"];
}
控制层使用
  1. UIButton
- (void)testUIButton{
    UIButton *racBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    racBtn.backgroundColor = [UIColor redColor];
    [self.view addSubview:racBtn];
    [racBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view);
        make.top.equalTo(self.mas_topLayoutGuide);
        make.width.equalTo(@100);
        make.height.equalTo(@50);
    }];
    [[racBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"点击了");
    }];
}
  1. UITextField
- (void)testTextField{
    UITextField *text = [[UITextField alloc]init];
    text.frame = CGRectMake(120, 100, 100, 50);
    [self.view addSubview:text];
    [text.rac_textSignal subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"----testTextField---%@",x);
    }];
}
  1. KVO
- (void)testKVO{
    [RACObserve(self, name) subscribeNext:^(id  _Nullable x) {
        NSLog(@"-------change---%@", x);
    }];
}
  1. NSNotificationCenter
- (void)testNotification{
    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"com.xiaobing.cn" object:nil] subscribeNext:^(NSNotification * _Nullable x) {
        NSLog(@"----testNotification----%@", x);
    }];
}
高阶函数
  1. filter
    还拿UITextField举例
[[text.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
        if (value.length > 6){
            text.text = [value substringToIndex:6];
        }
        return value.length < 7;
    }] subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"----filter----%@", x);
    }];

上边代码的结果是 文本框中最多输入6个字符 并且 只有满足长度小于7条件的时候 NSLog(@"----filter----%@", x); 才会执行

  1. flattenMap
    还拿KVO 来举例
[[RACObserve(self, name) flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value) {
        return [RACReturnSignal return:[NSString stringWithFormat:@"给我多加一个 %@",value]];
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"---RACReturnSignal------%@", x);
    }];

上述代码输出的结果 就是 每一次name发生变化 都会拼接上 ”给我多加一个 “

  1. combineLatestWith 和 reduce
- (void)testCombineLastest{
    [[RACSignal combineLatest:@[RACObserve(self, name), RACObserve(self, age)] reduce:^id (NSString *c1, NSNumber *c2){
        
        return [NSString stringWithFormat:@"%@的年龄是 %d", c1, (int)c2.intValue];
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"-----testCombineLastest---%@", x);
    }];
}

combineLatestWith 将两个信号进行组合 reduce 是将两个值 进行合并输出

  1. takeUntil
- (void)testTakeUntil{
    RACSubject *subject1 = [RACSubject subject];
    RACSubject *subject2 = [RACSubject subject];
    [[subject1 takeUntil:subject2] subscribeNext:^(id  _Nullable x) {
        NSLog(@"----takeUntil----%@", x);
    }];
    [subject1 sendNext:@"11"];
    [subject1 sendNext:@"22"];
    [subject2 sendCompleted];
    [subject1 sendNext:@"33"];
}

解释 订阅的是subject1的信号 当 subject2 发送过 或者完成一个信号时 subject1的订阅就不再起作用了

  1. takeLast
- (void)testTakeLast{
    RACSubject *subject = [RACSubject subject];
    [[subject takeLast:2] subscribeNext:^(id  _Nullable x) {
        NSLog(@"----testTakeLast----%@", x);
    }];
    [subject sendNext:@"11"];
    [subject sendNext:@"22"];
    [subject sendNext:@"33"];
    [subject sendNext:@"44"];
    [subject sendCompleted];
}

解释 这里只会 接收到 33 44的回调 注意注意 这里必须调用 sendCompleted

MVVM 小试牛刀

实现功能就是 成语列表的展示 和 成员的审核

  1. 定义Model 类
@interface PeopleModel : NSObject

@property(nonatomic, copy)NSString *name;
@property(nonatomic, assign)int age;
@property(nonatomic, assign)BOOL isVerified;
@end
  1. 定义viewModel类
@class PeopleModel;
@interface PeopleViewModel : NSObject

@property(nonatomic, strong)NSMutableArray *peoples;
@property(nonatomic, strong)RACSubject *refreshSignal;

- (instancetype)init;
- (void)reloadData;
- (PeopleModel *)modelFromIndex:(NSInteger)index;
- (void)verifyPeople:(NSInteger)index;
- (NSString *)verifyStatus:(NSInteger)index;
@end
  1. 核心显示类
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    NSString *ident = @"cell";
    MainCell *cell = [tableView dequeueReusableCellWithIdentifier:ident];
    if(!cell){
        cell = [[MainCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ident];
    }
    NSObject *peopleObj = (NSObject *)[self.peopleVM modelFromIndex:indexPath.row];
    NSNumber *age = [peopleObj valueForKey:@"age"];
    cell.nameLab.text = [peopleObj valueForKey:@"name"];
    cell.detailLab.text = [NSString stringWithFormat:@"年龄是 %d", age.intValue];
    [cell.verifiedBtn setTitle:[self.peopleVM verifyStatus:indexPath.row] forState:UIControlStateNormal];
    @weakify(self)
    [[cell.verifiedBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        @strongify(self)
        [self.peopleVM verifyPeople:indexPath.row];
    }];
    
    return cell;
}
总结

个人觉得无论是MVC 还是MVVM 没有更好的架构 只有更合适的架构,首先第一点我们的数据Model层跟UI层肯定是不能有关联的,这就是所谓的解耦和,UI层不能引入Model ,这里有不少程序员包括我自己也写过把 Model直接传如Cell中 进行数据的配置,这样其实耦合度非常高,把数据的配置放在Controller的cellForRowAtIndexPath中去做 还勉强可以,毕竟C这一层就是控制数据显示的。但是苹果原生的Controller 貌似负责了很多东西,UITableView 也是UI层的东西 这里却放在了Controller中,个人觉的也不是很合适,那么如果把UITableView再单独封装到一个View中呢 又比较麻烦,所以我比较喜欢MVVM的模式,逻辑层单独抽离,把所有东西都变成输入和输出,用户的动作引起Model的改变是输入,Model改变后的结果就是输出,比如从待审核到审核状态。MVVM Controll就是一个完全的数据配置层了,整个功能中就只耦合了ViewModel 这一层。以上只是我的个人观点,大神们有不同观点可以一起探讨。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值