美文网首页MVVM. RACiOS Developer
ReactiveCocoa (RAC) TableView(数据

ReactiveCocoa (RAC) TableView(数据

作者: 柠檬草YF | 来源:发表于2017-05-22 19:05 被阅读342次

    上一篇写了点简单的 KVO的数据绑定,刚了解这个特性的时候,我就想到了 利用到tableview上,感觉可以实现一种非常简单的绑定 model 和cell 的方式,但是经过实践 ,是会出现Bug的,再研究,然后解决掉这个Bug后,感觉对Cell的绑定 操作有点多,对cell展示的流畅性 感觉会产生阻碍,所以又放弃了这种方式,特别简单的Cell还是可以用的,下面让我们来 一起探讨下吧

    承接上篇

    [RACObserve(model, title) subscribeNext:^(NSString *x) {
            self.textLabel.text = x;
    }];
    

    我们经常会有改变cell对应的Model的属性,然后要更新到Cell上的,一般我的做法是 改变Model的属性后,

    1.找到Model对应的cell
    2.刷新 Model对应的Cell
    

    应该会有一大部分人都是这样做的,如果有更好的办法请评论联系我,回归正题,结合 RAC 我们可以把 Model的属性和 Cell的subviews(label imageView等)绑定在一起,这样就只需要 改变Model的属性的值,就会自动调用 rac的block,cell.m里的代码如下

    -(void)bindModel:(YFRACTestModel *)model
    {
        [RACObserve(model, title) subscribeNext:^(NSString *x) {
            self.textLabel.text = x;
        }];
        
        [RACObserve(model, sex) subscribeNext:^(NSString *x) {
            self.detailTextLabel.text = x;
        }];
    }
    

    好像很方便呢,一口气写 10个列表好像都不费力了呢
    我也高兴了好一阵子,觉得 春天到了,写程序也是一件不累人多拿钱的活呢,仔细一想 我的天哪,Bug已经悄无声息的渗透了进来,

    让我们来 分析下,

    bindModel: 这个方法是给Cell绑定数据用的,
    由于Cell是复用的,所以同一个Cell可能 执行 好多次 bindModel: 方法,
    也就意味着model的属性 和 cell的UI 会经过多次的绑定,
    而且 新的Model的绑定并不会覆盖掉 旧的model的绑定,
    这就导致了 cell 绑定了多个Model的属性,
    改变任何一个Model的值,都会更新cell的显示,这显然不是我们想要的
    我们写个tableView的Demo来验证下,
    点击cell改变Model的值,看看哪个Cell会更新,
    附上 点击cell的代码
    
     if (indexPath.row - 10 < 0)
     {
         NSLog(@"请点击更下方的cell");
         return;
     }
    
    YFRACTestModel *model = self.dataArray[indexPath.row - 10];
    model.sex = @"00000";
    

    效果

    000000.gif

    通过这张图,我们看到了 点击 当前cell改变相差10个下标的Model的值,相差1个下表的cell 更新了UI,这显然是一个bug了

    Demo代码
    https://pan.baidu.com/s/1o8NUh1S 提取码:v624

    Bug出现,就该干掉,让我们 解决掉它
    既然Bug是由于 多次绑定出现的,那我们就在新的绑定关系发生前,把旧的绑定关系除掉,经过调研,这确实是可行的,我们看下代码
    cell.m 代码

    
    #import "YFTestCell.h"
    
    #import <ReactiveCocoa.h>
    
    @implementation YFTestCell
    {
        RACDisposable * _lastTitleSig;
        RACDisposable * _lastSexSig;
    }
    
    -(void)bindModel:(YFRACTestModel *)model
    {
    // 解除 上一个model的 绑定
        [_lastTitleSig dispose];
        [_lastSexSig dispose];
        __weak typeof(self)weakS = self;
        RACDisposable * titleSig = [RACObserve(model, title) subscribeNext:^(NSString *x) {
            weakS.textLabel.text = x;
        }];
        
      RACDisposable * sexSig = [RACObserve(model, sex) subscribeNext:^(NSString *x) {
            weakS.detailTextLabel.text = x;
        }];
    // 记录 当前model的 绑定,下一次绑定时,先解除绑定
        _lastTitleSig = titleSig;
        _lastSexSig = sexSig;
    }
    @end
    

    重新运行我们的Demo,发现没有问题了,也达到了我们最初的想法,但是 感觉在cell 绑定数据时发生了太多的操作,RAC 的绑定和解除绑定也有一定的消耗CPU,如果cell过于复杂绑定太多的属性,对于cell的流畅性会有一定的影响,所以采用此方案时,要慎重呀

    致此 ,本文 结束,期待大家的评论互动,如果帮到了你,请喜欢收藏下哦,下次见

    相关文章

      网友评论

        本文标题:ReactiveCocoa (RAC) TableView(数据

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