Cell重用时数据混乱的管理方法
UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件。上面主要是一个个的UITableViewCell,可以让UITableViewCell响应一些点击事件,也可以在UITableViewCell中加入UITextField或者UITextView等子视图,使得可以在cell上进行文字编辑。
UITableView中的cell可以有很多,一般会通过重用cell来达到节省内存的目的:通过为每个cell指定一个重用标识符(reuseIdentifier),即指定了单元格的种类,当cell滚出屏幕时,会将滚出屏幕的单元格放入重用的queue中,当某个未在屏幕上的单元格要显示的时候,就从这个queue中取出单元格进行重用。
但对于多变的自定义cell,有时这种重用机制会出错。比如,当一个cell含有一个UITextField的子类并被放在重用queue中以待重用,这时如果一个未包含任何子视图的cell要显示在屏幕上,就会取出并使用这个重用的cell显示在无任何子视图的cell中,这时候就会出错。
常规配置如下 当超过tableView显示的范围的时候 后面显示的内容将会和前面重复
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier=@"aaa";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
if (indexPath.row%2 == 0) {
cell.textLabel.text = [dataArr objectAtIndex:indexPath.row];
cell.imageView.image = [photoArr objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor greenColor];
}else
{
self.leftLabel = [[UILabel alloc]initWithFrame:CGRectMake(280, 0, 40, 40)];
self.leftLabel.text = [dataArr objectAtIndex:indexPath.row];
[cell addSubview:self.leftLabel];
self.leftimageView = [[UIImageView alloc]initWithFrame:CGRectMake(320, 0, 66, 44)];
self.leftimageView.image = [photoArr objectAtIndex:indexPath.row];
[cell addSubview:self.leftimageView];
cell.backgroundColor = [UIColor yellowColor];
}
return cell;
}
方案一 取消cell的重用机制,通过indexPath来创建cell 将可以解决重复显示问题 不过这样做相对于大数据来说内存就比较吃紧了
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if (indexPath.row%2 == 0) {
cell.textLabel.text = [dataArr objectAtIndex:indexPath.row];
cell.imageView.image = [photoArr objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor greenColor];
}else
{
self.leftLabel = [[UILabel alloc]initWithFrame:CGRectMake(280, 0, 40, 40)];
self.leftLabel.text = [dataArr objectAtIndex:indexPath.row];
[cell addSubview:self.leftLabel];
self.leftimageView = [[UIImageView alloc]initWithFrame:CGRectMake(320, 0, 66, 44)];
self.leftimageView.image = [photoArr objectAtIndex:indexPath.row];
[cell addSubview:self.leftimageView];
cell.backgroundColor = [UIColor yellowColor];
}
return cell;
}
方案二 让每个cell都拥有一个对应的标识 这样做也会让cell无法重用 所以也就不会是重复显示了 显示内容比较多时内存占用也是比较多的和方案一类似
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:@"cell%ld%ld",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (indexPath.row%2 == 0) {
cell.textLabel.text = [dataArr objectAtIndex:indexPath.row];
cell.imageView.image = [photoArr objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor greenColor];
}else
{
self.leftLabel = [[UILabel alloc]initWithFrame:CGRectMake(280, 0, 40, 40)];
self.leftLabel.text = [dataArr objectAtIndex:indexPath.row];
[cell addSubview:self.leftLabel];
self.leftimageView = [[UIImageView alloc]initWithFrame:CGRectMake(320, 0, 66, 44)];
self.leftimageView.image = [photoArr objectAtIndex:indexPath.row];
[cell addSubview:self.leftimageView];
cell.backgroundColor = [UIColor yellowColor];
}
return cell;
}
方案三 只要最后一个显示的cell内容不为空,然后把它的子视图全部删除,等同于把这个cell单独出来了 然后跟新数据就可以解决重复显示
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; //出列可重用的cell
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
if (indexPath.row%2 == 0) {
cell.textLabel.text = [dataArr objectAtIndex:indexPath.row];
cell.imageView.image = [photoArr objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor greenColor];
}else
{
self.leftLabel = [[UILabel alloc]initWithFrame:CGRectMake(280, 0, 40, 40)];
self.leftLabel.text = [dataArr objectAtIndex:indexPath.row];
[cell addSubview:self.leftLabel];
self.leftimageView = [[UIImageView alloc]initWithFrame:CGRectMake(320, 0, 66, 44)];
self.leftimageView.image = [photoArr objectAtIndex:indexPath.row];
[cell addSubview:self.leftimageView];
cell.backgroundColor = [UIColor yellowColor];
}
return cell;
}
Cell重用时数据混乱的管理方法的更多相关文章
- WPF拖动DataGrid滚动条时内容混乱的解决方法
WPF拖动DataGrid滚动条时内容混乱的解决方法 在WPF中,如果DataGrid里使用了模板列,当拖动滚动条时,往往会出现列表内容显示混乱的情况.解决方法就是在Binding的时候给Update ...
- 解决UITableView中Cell重用机制导致内容出错的方法总结
UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点 ...
- ios UITableView中Cell重用机制导致内容重复解决方法
UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点 ...
- jvm入门及理解(四)——运行时数据区(堆+方法区)
一.堆 定义: Heap,通过new关键字创建的对象,都存放在堆内存中. 特点 线程共享,堆中的对象都存在线程安全的问题 垃圾回收,垃圾回收机制重点区域. jvm内存的划分: JVM内存划分为堆内存和 ...
- JVM 运行时数据区(二)
@ 目录 运行时数据区 共享区 堆区 方法区 隔离区 虚拟机栈 栈帧 本地方法栈 程序计数器 运行时数据区 JVM 运行时数据区主要分为5块 方法区 JDK1.8以后叫做元数据区(Metaspace) ...
- 解决Cell重用内容混乱的几种简单方法,有些方法会增加内存
重用实现分析 查看UITableView头文件,会找到NSMutableArray* visiableCells,和NSMutableDictnery* reusableTableCells两个结构 ...
- Java虚拟机一 运行时数据区(栈、堆、方法区等)
Java虚拟机的内存管理主要分两点:内存分配以及内存回收.· 一.内存分配图: 注: 所占区域的大小与实际的内存大小比例并无直接关系. 解读: 1.如图,分成两种颜色的内存区域,其中蓝色的是线程隔离的 ...
- 你必须了解的java内存管理机制(一)-运行时数据区
前言 本打算花一篇文章来聊聊JVM内存管理机制,结果发现越扯越多,于是分了四遍文章(文章讲解JVM以Hotspot虚拟机为例,jdk版本为1.8),本文为其中第一篇.from 你必须了解的java内存 ...
- oracle使用还原段的目的和还原数据的管理方法及还原段的类型
一.引入还原段主要有3个目的: 1.事务回滚:主要是针对rollback语句起作用 2.事务恢复:非正常关闭数据库即非保留事务级关闭数据库(abort.immediate)或者数据库instance崩 ...
随机推荐
- Python 第十三节 文件操作
A 1.首先文件读写操作有以下几种模式: a\a+ w\w+ r\r+ a模式:追加_写入模式,写入指针默认在开头,如果文件存在将在开头追加写入,如果文件不存在将创建文件再写入. a+模式: ...
- java传值与传引用总结
基本数据类型 我们先来看一个代码 public class ParamTest { public static void main(String[] arge) { double percent = ...
- Quart.Net分布式任务管理平台
无关主题:一段时间没有更新文章了,与自己心里的坚持还是背驰,虽然这期间在公司做了统计分析,由于资源分配问题,自己或多或少的原因,确实拖得有点久了,自己这段时间也有点松懈,借口就不说那么多 ...
- Install a Redmine on Ubuntu system
# How to install a Redmine on Ubuntu system Ref to: https://www.linode.com/docs/applications/project ...
- mvc4 实现自己的权限验证 仿Authorize与AllowAnonymous原理
参考文章 :http://www.cosdiv.com/page/M0/S878/878978.html 实现的效果:在控制器上(Controller)验证权限,在动作(Action)上不验证. 用M ...
- Rank of Tetris
Rank of Tetris Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- SQLAlchemy复杂查询
最近个人用python + flask搞了一个小项目,ORM用到的是SQLAlchemy. SQLAlchemy的查询方式非常灵活,你所能想像到的复杂SQL 语句,基本上都可以实现.这里简单的总结 ...
- zepto在操作dom的selected和checked属性时尽量使用prop方法
zepto在操作dom的selected和checked属性时尽量使用prop方法.
- Problem H: STL——括号匹配
Description 给出一堆括号,看其是否匹配,例如 ().()().(()) 这样的括号就匹配, )(.)()) 而这样的括号就不匹配 Input 每一行代表一组测试样例,每组测试样 ...
- SQL Server Backup & Restore
USE [master]; GO CREATE DATABASE test; GO CREATE DATABASE test2; GO BACKUP DATABASE test TO DISK = ' ...