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崩 ...
随机推荐
- Windows下Mysql5.7开启binlog步骤及注意事项
1.查看是否开启了binlog:show binary logs; 默认情况下是不开启的. 2.开启binlog:修改mysql的配置文件my.ini.添加如下配置: 该文件默认不允许修改,需要右键“ ...
- 217. Contains Duplicate (leetcode)
Given an array of integers, find if the array contains any duplicates. Your function should return t ...
- 小技巧:Oracle:sqlplus 显示行列字符数
遇到这种情况可以判断:行显示字符数不够,可以增加行显示字符数 01.可以当前会话HR@ACE >set line 400; 02.上面的方法其它会话不生效,懒不想每次设置怎么办? Oracle: ...
- LeetCode 15. 3Sum(三数之和)
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...
- 对foreach循环的思考
阿里java开发手册已经发表,很多都值得认真研究思考,看到零度的思考题,没忍住研究了一下. 零度的思考:https://mp.weixin.qq.com/s/dDR21k30s6ZVfDvl8BVQm ...
- 视频加载logo 2
推荐这个网站 http://www.flaticon.com/ http://www.flaticon.com/search?word=spinner 旋转图标 http://www.flatico ...
- UWP 磁贴设置
一:需求 一款好看好用的应用,对于UWP来说,动态的磁贴必不可少. 二:TileUpdateManager类 和TileUpdater类 如果需要更改或更新应用的磁贴,那么首先需要获得TileUpda ...
- print、println与printf之间的区别
//print没有换行的而println有自动换行功能.实例:uprint.java class uprint{public static void main(String arg[]){int i, ...
- 本地文件与服务器文件同步shell脚本。
#!/bin/sh read -t 30 -p "请输入项目名:" name echo -e "\n" echo "项目名为:$name" ...
- Andrew 机器学习课程笔记
Andrew 机器学习课程笔记 完成 Andrew 的课程结束至今已有一段时间,课程介绍深入浅出,很好的解释了模型的基本原理以及应用.在我看来这是个很好的入门视频,他老人家现在又出了一门 deep l ...