操蛋的UITableView重用机制
1,背景
你可能会遇见一下情况:
使用UITableView加载数据,比如你的每一个cell上面有一个UITextField,当你在第一个cell的UITextField中写下了内容,开始下滑UITableView,你会发现由于UITableView重用机制的影响,你的第一个UITextField的值会发生变化,令人费解啊,抓狂!
之类的情况可能很多,下面咱们就总结一下发生这种情况的原因,针对这种原因,咱们找到对应的解决办法。
2,用自己的话说UITableView的重用机制
当遇见这中情况的时候,我问过好多个ios程序员,他们多数的解决办法是直接不让它重用了,当然了,这样的话,表面上确实解决了问题,但是却给自己的程序带来了很大的隐患。我们做东西,应该去想着做最好的东西出来,不能这样草草的应付。
好了,言归正传。
所谓重用机制,就是模板共用一套,换的是内容。比如;view上显示七个cell,当第一个cell消失,第八个cell出现,那么第八个cell用的还是第一个cell,只不过他把第一个cell的内用换成了自己的。这就是重用的原理。问题就出现在他在换内容的时候,没换好,就出现了错误。
那么为什么会出现这种错误呢,为什么我们替换内容的时候根本就没有错,重用后还会出现错误呢?
不说废话 直接说我遇见的问题以及我的解决办法:
我的问题是右边的UITableView在上下滑动的时候按钮出现了重用,点过之后的按钮会发生变化,分成两个按钮,一个加菜按钮一个减菜按钮
当我点了第一个cell后,分裂成功,我将UITableView向下滑,却出现了第一个cell的按钮又变回了原型。
出现的原因:这个cell是我自定义的,这个按钮的状态是没有记录的,一次重用后他会和原来的状态一样。
解决办法:我是这样想的解决办法,之所以个重用是因为第一个和第八个没有特别的标注,我必须想一个区分第一个和第八个的属性,那么就有了indexpath.row,一位他们即使在重用这个值也不会相同,因此我们就用这个属性解决这个操蛋的问题。
好了,原理是这样,来看看我的解决代码吧;
[self.dataArr enumerateObjectsUsingBlock:^(NSDictionary * obj, NSUInteger idx, BOOL *stop) {
[self.tempDotNumberDic setValue:[obj valueForKey:@"number"] forKey:[obj valueForKey:@"ProID"]];
}];
说明:dataArr是tableview的数据源,tempDotNumberDic是一个记录点菜份数的字典,他的key是点菜id(因为id是唯一的,这样可以区分开),他的value是点菜份数。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView.tag == 100)
{
static NSString * strMark = @"cellMark";
DishesClassCell * cell = [tableView dequeueReusableCellWithIdentifier:strMark];
if (cell == nil)
{
cell = [[DishesClassCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strMark];
}
if (indexPath.row<self.myClassArr.count)
{
cell.textContentLab.text = [[self.myClassArr objectAtIndex:indexPath.row] valueForKey:@"ClassName"];
}
if (self.tempClassDic.count>0)
{
NSString * result = [self.tempClassDic valueForKey:[NSString stringWithFormat:@"%d",indexPath.row]];
if ([result isEqualToString:@"1"])
{
cell.backgroundImageView.image = [UIImage imageNamed:@"DishClass06.png"];
}
else
{
cell.backgroundImageView.image = [UIImage imageNamed:@"DishClass05.png"];
}
}
return cell;
} NSString *str1 = [NSString stringWithFormat:@"cellmark%d",selectRow];
NSString * strMark1 = str1; //不停类别用不同的重用标示符,目的是为了不同分类同一位置的重用现象。
DishesDetailListCell * cell1 = [tableView dequeueReusableCellWithIdentifier:strMark1];
__block int dotNumber = 0;
if (indexPath.row < self.myProArr.count)
{
__block NSString * proID;
NSString * currID = [[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"ProID"];
[self.dataArr enumerateObjectsUsingBlock:^(NSDictionary * obj, NSUInteger idx, BOOL *stop) {
proID = [obj valueForKey:@"ProID"];
if ([currID isEqualToString:proID])
{
dotNumber = [[[[DataBase selectNumberFromProId:[currID intValue]] objectAtIndex:0] valueForKey:@"number"] intValue];
}
}];
} if (cell1 == nil)
{
cell1 = [[DishesDetailListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strMark1 andDotNumber:dotNumber];
}
cell1.dishView.myLab.text = [NSString stringWithFormat:@"点%d份",dotNumber];
int resylt = [[self.tempDotNumberDic valueForKey:[[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"ProID"]] intValue];
if (resylt == 0)
{
[cell1.dishView zeroState];
}
else
{
[cell1.dishView initView:resylt];
}
if (indexPath.row%2 == 0)
{
cell1.backgroundImageView.image = [UIImage imageNamed:@"5.png"];
}
else
{
cell1.backgroundImageView.image = [UIImage imageNamed:@"6.png"];
}
cell1.selectionStyle=UITableViewCellSelectionStyleNone;
cell1.selectedBackgroundView = [[UIView alloc] initWithFrame:cell1.frame];
cell1.titleLab.text = [[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"ProName"];
NSString * str = @"¥";
NSString * priceStr = [[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"prices"];
cell1.priceLab.text = [str stringByAppendingFormat:@"%@",priceStr];
cell1.dishView.price = [priceStr doubleValue];
cell1.dishView.index = indexPath.row; [cell1.dishView.rightButton addTarget:self action:@selector(rightButtonClickEvent:) forControlEvents:UIControlEventTouchUpInside];
[cell1.dishView.leftButton addTarget:self action:@selector(leftButtonClickEvent:) forControlEvents:UIControlEventTouchUpInside];
[cell1.dishView.bigButton addTarget:self action:@selector(bigButtonClickEvent:) forControlEvents:UIControlEventTouchUpInside]; NSString * pathURL = ALL_URL;
NSURL * url = [NSURL URLWithString:[pathURL stringByAppendingFormat:@"%@",[[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"ProductImg"]]];
[cell1.leftImageView setImageWithURL:url placeholderImage:[UIImage imageNamed:ALL_NO_IMAGE]];
return cell1;
}
看红色部分的代码,这点就是避免问题出现的办法,因为这个值是不同的cell值不同。
感觉自己的想法没有表达清楚,有什么问题直接留言。
操蛋的UITableView重用机制的更多相关文章
- UI之UItableView重用机制的性能问题
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- IOS开发—UITableView重用机制的了解
引言 对于一个UITableView而言,可能需要显示成百上千个Cell,如果每个cell都单独创建的话,会消耗很大的内存.为了避免这种情况,重用机制就诞生了. 假设某个UITableView有100 ...
- iOS - UITableView中Cell重用机制导致Cell内容出错的解决办法
"UITableView" iOS开发中重量级的控件之一;在日常开发中我们大多数会选择自定Cell来满足自己开发中的需求, 但是有些时候Cell也是可以不自定义的(比如某一个简单的 ...
- iOS基础篇(十三)——UITableView(一)重用机制
UITableView是app开发中常用到的控件,功能很强大,常用于数据的显示.在学习UITableView使用之前,我们先简单了解一下: 1.UITableView的重用机制 UITableView ...
- UITableView动态存放、重用机制
一.UITableView动态存放 #import "ViewController.h"@interface ViewController ()<UITableViewDel ...
- 解决UITableView中Cell重用机制导致内容出错的方法总结
UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点 ...
- iOS学习笔记(4)— UITableView的重用机制
UITableView中的cell是动态的,在使用过程中,系统会根据屏幕的高度(480)和每个cell的高度计算屏幕中需要显示的cell的个数.比如,cell高度为90.那么480 / 90 = 5 ...
- ios UITableView中Cell重用机制导致内容重复解决方法
UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点 ...
- iOS之UITableView中的cell因为重用机制导致新的cell的数据出现重复或者错乱
UITableView中的cell可以有很多,一般会通过重用cell来达到节省内存的目的:通过为每个cell指定一个重用标识符(reuseIdentifier),即指定了单元格的种类,当cell滚 ...
随机推荐
- 关于win7系统的Oracle安装时的[INS-30131]问题的解决方案
我是今天晚上安装的Oracle,结果在第二步遇到了这个问题,前后折腾了两个小时,百度了很多解决方案,终于解决了这个问题; 由于我的电脑系统还是win7的系统,其他的我没试过,不过也差不多都这么解决; ...
- Redis中各种方法的使用
①set ; i< ; i++) { // 不可以重复添加数据 client.AddItemToSet(KKey, "dong升-" + i); } client.Remov ...
- Linux流量监控工具使用总结 - iftop
在类Unix系统中可以使用top查看系统资源.进程.内存占用等信息.查看网络状态可以使用netstat.nmap等工具.若要查看实时的网络流量,监控TCP/IP连接等,则可以使用iftop. 一.if ...
- python pdb调试以及sublime3快捷键设置
python pdb调试以及sublime3快捷键设置 pdb调试 如果对gdb比较熟悉的话,pdb就很容易上手.以一个demo快速了解常用的调试命令. def test(a): while True ...
- karma note
karma 简介 karma不是一个测试框架,仅仅是启动了一个httpServer karma仅仅是一个跑测试的平台(runner), 我们可以使用各种测试框架, 如: Jasmine Mocha Q ...
- cocos2dx 坐标和锚点
cocos2dx中使用opengl坐标系,左下角为坐标原点,在大部分情况下,都是使用这种坐标系的. 当我们创建了一个渲染对象到窗口后,那么这个对象本身也是也是有自己的坐标系的,这种坐标系是节点自己的坐 ...
- Codeforces 703D Mishka and Interesting sum(树状数组+扫描线)
[题目链接] http://codeforces.com/contest/703/problem/D [题目大意] 给出一个数列以及m个询问,每个询问要求求出[L,R]区间内出现次数为偶数的数的异或和 ...
- [spring+springmvc+mybatis实践]学生社团管理系统
一.简介 ssm框架为现在十分流行的mvc主流框架.mybatis负责与数据库交互,springmvc与spring完美适配,负责控制器和视图渲染.之前有初步学习过ssm框架,这次借学校里的web课设 ...
- 编译器DIY——词法分析
在上一篇文章中已经介绍了读文件的操作,那么这一篇文章中将会细致解释词法分析. 在源文件里解析出的单词流必须识别为保留字,标识符,常量,操作符和界符五大类 1.显然我们须要列举出全部的保留字,而这里与保 ...
- 不是技术牛人,如何拿到国内IT巨头的Offer(1)
转自:http://developer.51cto.com/art/201404/436685.htm 不久前,byvoid面阿里星计划的面试结果截图泄漏,引起无数IT屌丝的羡慕敬仰.看看这些牛人,N ...