ReactiveCocoa (RAC) TableView(数据篇)

上一篇写了点简单的 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";

效果

ReactiveCocoa (RAC) TableView(数据篇)_第1张图片
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 

@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(数据篇))