UITableViewCell的重复利用机制有效地节省内存开销和提升程序性能。 缓存
tableView拥有一个缓存池,存放未在使用(没有显示在界面)的cell。性能
tableView有一行cell要显示时先从缓存池里找,没有则建立,有一行cell隐藏不须要显示时就放到缓存池。动画
//cellForRow 代码spa
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{3d
static NSString *ID = @"test"; // cell循环利用标识为”test”blog
//从当前tableView对应的缓存池里找标识为”test”的cell;ip
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];内存
//若是缓存池里没有,即cell为空,建立新的cellit
if(!cell){table
cell = [[UITableViewCell alloc]init];
}
return cell;
}
这里引入一个数据模型 LSUser(用户模型),
属性: name(NSString, 名字), vip(BOOL, 是否会员)
图3-1
//cellForRow方法中设置数据
//设置用户名称
cell.textLabel.text = user.name;
//若是用户是vip,设置用户名称颜色为红色
if(user.vip){
cell.textLabel.textColor = [UIColor redColor];
}
因为吴八不是会员,跳过if 语句,吴八名称颜色应为黑色,但实际上却保留着陈七cell0设置的会员颜色红色。这是循环利用一个简单的问题所在。
假设if 语句中添加了对称的设置语句,这个问题就不会出现。
if(user.vip){
cell.textLabel.textColor = [UIColor redColor];
}else{
cell.textLabel.textColor = [UIColor blackColor];
}
UITableViewCell的循环利用要求咱们对称地设置视图的外观和状态。
实际上这个事例的循环利用问题能够认为出在cell.textLabel.textColor默认颜色为黑色上,假设需求是非会员名称颜色为蓝色,因而设置数据时:
cell.textLabel.textColor = user.vip ? [UIColor redColor]: [UIColor blueColor];
认真思考下。。。
这里有个需求:点击了某一行cell, 当前cell用户名称颜色改成紫色, 其他为原来的黑色
可能你会这么作:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.textColor = [UIColor purpleColor];
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.textColor = [UIColor blackColor];
}
暂时看来确实符合了需求,点击的当前行名称颜色为紫色,其他为黑色
可是,当你拖动tableView, 当前行隐藏,随意拖动,愕然地发现某一行名称颜色为紫色,再回到原先点击的当前行,名称颜色却为黑色而不是紫色。
这也是循环利用的问题。接下来解决这个问题。
当一行cell将要显示时,会调用tableView的数据源方法-tableView:cellForRowAtIndexPath;
循环利用影响影响cell显示,不会影响原始数据,该方法中进行了数据设置的步骤,利用它介绍两种解决方案:
1) 循环利用不会影响indexPath,indexPaht是惟一的。
首先拥有一个NSIndexPath类型的selectedIndexPath属性,用于纪录当前选中行,在didSelectRowAtIndexPath方法中进行赋值。
而后在-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法中,
//设置数据
//取出对应行的数据模型
LSUser *user = self.users[indexpath.row];
//设置用户名称
cell.textLabel.text = user.name;
//根据是不是选中行设置名称颜色
if(self.selectedIndexPath == indexPath){
cell.textLabel.textColor = [UIColor purpleColor];
}else{
cell.textLabel.textColor = [UIColor blackColor];
}
2) 对数据动手,从数据模型中派生一个专对于该cell的数据模型,追加相应的属性,而后在相应的地方对数据进行处理和设置。这里再也不赘述,该方案适合处理复杂的状况,好比如不必定是选中与非选择两种状态,还多是三种以上状态,或者cell的动画效果,或者须要[tableView reloadData]等的状况。