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重用机制的更多相关文章

  1. UI之UItableView重用机制的性能问题

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  2. IOS开发—UITableView重用机制的了解

    引言 对于一个UITableView而言,可能需要显示成百上千个Cell,如果每个cell都单独创建的话,会消耗很大的内存.为了避免这种情况,重用机制就诞生了. 假设某个UITableView有100 ...

  3. iOS - UITableView中Cell重用机制导致Cell内容出错的解决办法

    "UITableView" iOS开发中重量级的控件之一;在日常开发中我们大多数会选择自定Cell来满足自己开发中的需求, 但是有些时候Cell也是可以不自定义的(比如某一个简单的 ...

  4. iOS基础篇(十三)——UITableView(一)重用机制

    UITableView是app开发中常用到的控件,功能很强大,常用于数据的显示.在学习UITableView使用之前,我们先简单了解一下: 1.UITableView的重用机制 UITableView ...

  5. UITableView动态存放、重用机制

    一.UITableView动态存放 #import "ViewController.h"@interface ViewController ()<UITableViewDel ...

  6. 解决UITableView中Cell重用机制导致内容出错的方法总结

    UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点 ...

  7. iOS学习笔记(4)— UITableView的重用机制

    UITableView中的cell是动态的,在使用过程中,系统会根据屏幕的高度(480)和每个cell的高度计算屏幕中需要显示的cell的个数.比如,cell高度为90.那么480 / 90 = 5  ...

  8. ios UITableView中Cell重用机制导致内容重复解决方法

    UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点 ...

  9. iOS之UITableView中的cell因为重用机制导致新的cell的数据出现重复或者错乱

      UITableView中的cell可以有很多,一般会通过重用cell来达到节省内存的目的:通过为每个cell指定一个重用标识符(reuseIdentifier),即指定了单元格的种类,当cell滚 ...

随机推荐

  1. BZOJ 4311: 向量( 按时间分治 + 线段树 )

    离线, 然后按时间分治, 每个向量都有出现时间[l, r], 直接插入时间线段树(一个向量只会影响O(logN)数量级的线段树节点). 在线段树每个节点弄出凸壳然后二分. 时间复杂度O(Nlog^2N ...

  2. C#学习日志 day 2 plus ------ hyper-V 开启方法

    hyper-V的开启需要两个步骤. 第一是在bios中开启 virtualization technology--虚拟化技术 在process setting中改为enabled. 进入bios界面的 ...

  3. codeforces 633G. Yash And Trees dfs序+线段树+bitset

    题目链接 G. Yash And Trees time limit per test 4 seconds memory limit per test 512 megabytes input stand ...

  4. .net mvc笔记1_ The MVC Pattern

    1.controller中的每一个public method被称为action method,意味着你可以从web上通过URL来调用它,以此来执行一个action. 2.当我们从action meth ...

  5. pyqt中使用matplotlib绘制动态曲线 – pythonic

    一.项目背景: 看了matplotlib for python developers这本书,基本掌握了在pyqt中显示曲线的做法,于是自己写一个. 二.需求描述: 1)X轴显示时间点,显示长度为1分钟 ...

  6. HDU 5054 Alice and Bob

    #include <cstdio> int main(){ int n,m,x,y; while(~scanf("%d%d%d%d",&n,&m,&am ...

  7. CH Round #57 - Story of the OI Class 凯撒密码

    很有意思的一道题目 考场上想的是HASH成一个整数,把末位asicc码值*1,依次乘*10,得到一个整数,然后利用等差性.唯一性快排Nlogn乱搞的 证明如下: 对于明文abcde 密文 bcdef ...

  8. C#实现 ffmpeg视频转码、播放

    近来公司项目要求实现全景相机的视频截取,但是截取的视频需求转码上传.经过研究采用ffmpeg转码,奉上一个详细介绍的博文: 最简单的基于FFMPEG的转码程序 主要是转码的操作过程,能够实现了从相机获 ...

  9. ubuntu openStack icehouse dashboard theme自定义

    1,ubuntu openStack 语言包locate

  10. JWPlayer 使用小记

    最后的效果 1.从官网下载JWPlayer 下载后的文件,标红部分是必要的文件. 2.Jquery可以使用1.6以上版本 <html><head> <title>G ...