上一篇写了点简单的 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的流畅性会有一定的影响,所以采用此方案时,要慎重呀
致此 ,本文 结束,期待大家的评论互动,如果帮到了你,请喜欢收藏下哦,下次见
网友评论