今天在研究SDWebImage和ASIHTTPRequest实现网络图片异步加载和本地缓存的时候,在UITableView显示图片的时候,出现了一些奇异的现象,比如:

1、TableView一次只能显示10行的图片,在所有图片都加载完后,滚动TableView,让隐藏在下面的行显示在屏幕上,而这些行(比如11行)的图像会先显示第1行的图片,然后在显示属于它自己的图片。以此类推,后面的行都会出现这样的问题!! 即使我们在所有行的图片都还没有下载完成的时候,滚动TableView,让第11行、12行等出现在屏幕上,但它们依旧会先显示错误的图片,然后再显示正确的图片。

2、在ASIHTTPRequest的Demo中,当图片加载后,滑动TableView,整个TableView的图片将会乱掉,整个TableView以循环的方式显示最后几行的图片。

一番查找后,发现之所以会出现这些问题,是因为我忽略了UITableView的重用机制的影响。进过适当的修改后,demo终于能够正常运行了。下面是一些相关的资料和解决方法。

=======================================================================

iphone重用机制是苹果为了实现大量数据显示而采用的一种节省内存的机制,比如在UITableView和ScrollView 等地方。为什么要“可重用”???对于我们的项目来说,内存控制是必不可少的,如果一个tableview有几百个cell,这个内存消耗是很大的,而且有些cell里面都有image之类的很占内存的资源存在的话,那这样很容易出现memory warning甚至crash掉,这不是我们想要看到的。对此,tableview实现了它自己的管理方法dequeueReusableCellWithIdentifier(ps:我们在某些项目中scrollview来显示很多张image,在scrollview滑动中也要这样处理,来避免内存的过度消耗,只不过tableview它已经实现了这个方法,而不用我们自己去写)。

但是在实际使用过程中,会有以下问题:

1、(苹果文档中不鼓励我们在UITableViewCell中添加subView,最好采用自定义Cell,将需要的SubView添加到Cell当中。)使用addSubView在每项上添加视图的时候会有重叠的现象。例如,UITableView中的Cell ,如果在cell上添加子视图,则在使用苹果的重用机制的时候,会重现子试图重叠的现象。或出现开头提到的两个问题。如果在数据量不是很多的时候,可以手动屏蔽掉UITableView的重用机制。

这里不得不提一下UITableView的重用机制:

UITableView的重用机制的实现关键在于下面这个的函数:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

首先,我们要清楚这一点,这个函数是做什么的,它的文档说明如下:
returns a reusable table-view cell object located by its identifier。它返回的是一个受identifier管理定位的可重用的tableViewCell,这里重点就在于“可重用”这3个字上。

我们来看它的实现方法,举个例子来说,在系统刚启动时,tableview可以显示多少个cell,在这里我们假定为10个,在刚开始的时候tableview会生成10个tableviewcell,并且对应有自己的tag值,假定为0-9。(ps:苹果官方的视频中也提到了,尽量避免频繁的add/remove view或者控件之类等。自定义啊自定义,相对于Android 空间的自定义,)所以采用下面的方法来实现:在tableview向上滚动的时候,tag为0的cell将不再显示;然后我们把tag为0的cell移动到tag为9的cell下面,重新设置相关的属性,然后将tag为1的cell移动到tag为0的cell下面……依此类推。这也就是所谓的“可重用”。

但是此时被移动的tag为0的cell的一些属性还是保持不变的(包括之前添加的subView),因此就会出现一些无厘头的bug(看了这么多,到这里是不是松了口气? )。

接下来我们就要使用多种的方法来干掉这个重用机制:

(1):

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell != nil) {

[cell release];  //怎么样?? 换了位置的Cell嚣张不了了吧....

}

(2): //和(1)的方法本质一样,略显啰嗦。

UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {

cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:CellIdentifier]autorelease];

}

NSArray*subviews = [[NSArrayalloc]initWithArray:cell.contentView.subviews];

for (UIView *subview in subviews) {

[subviewremoveFromSuperview];

}

[subviews release];

           //customer 

return cell;

}

(3)://丫的,组别都不一样,看你怎么重用。

NSString *CellIdentifier = [NSString stringWithFormat:@"cell%d",indexPath.row];
    
           UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
          if (cell == nil)

{
                               ........
                 }
         else{
                        return cell;
               }

虽然干掉了重构机制,但我还是时不时地会想念它,特别是在数据多的时候,使用重用机制会好对你的程序的内存使用和优化都有很重要的作用。 但是这样的话,如果想再cell上添加东西的话,重叠现象会很严重。好吧,鱼和熊掌捆绑销售啦啦!!使用xib给cell添加视图来添加视图吧......

具体步骤:

(1)新建一个基于UITableViewCell的类A和一个空白的xib。

(2)在A类中声明要添加的视图,例如IBOutlet UILabel *nameLabel,*timeLabel; ,注意:一要是使用  IBOutlet。

(3)将xib中的view删除,拖一个 UITableViewCell,然后将这个UITableViewCell的类改为基于A。再把相应的视图添在UITableViewCell上,并且与A类内定义的变量进行连接。这样准备工作就完成了。

(4)使用方法:

A* cell = (A*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {

NSArray* nib = [[NSBundle mainBundle] loadNibNamed:@"VideoCell" owner:self options:nil];

cell = [nib objectAtIndex:0];

}

然后只需在下面改变cell相应视图的属性就可以了。

补充:在使用地图MKMapView一会使用到重用机制,如果想要在MKPinAnnotationView添加视图的话,最好放弃那个重用机制,要不然效果会乱七八糟的(估计还有更好的处理方法)~~

    什么,你不喜欢用Xib?好吧,这个老外写的UITableView的代码,估计会合你的口味,实现方式如下:

    1、cell中的释放

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {

cell = [[[UITableViewCell alloc] init....] autorelease];

UITextField *field = ...;//初始化

[cell addSubView:field];//添加

[field release];//释放

}

2、通过遍历修改UILabel属性

  UITextField*field = nil;

for(UIView *v in cell.contentView.subviews)

{

if([v isMemberOfClass:[UILabel class]])

field = (UITextField *)v;

}

......//接下来修改field的属性

这种方法不敢说好不好,但是给我们提供了一种解决的思路,看大家的喜好了```

嗯,不小心了弄了这么个“长篇巨幅”,到处借鉴同时混加自己的东西,如有雷同,算我抄你的。

大家可以参考这篇文章:

http://hi.baidu.com/%CB%E6%B7%E7_1989/blog/item/077c8a944ae7a69ca877a41d.html
(不贴这链接的话,这个随风_1989估计饶不了我...)

iphone 重用机制相关推荐

  1. UITableView 重用机制

    iphone重用机制是苹果为了实现大量数据显示而采用的一种节省内存的机制,但是在实际使用过程中,会有以下问题: 1.使用addSubView在每项上添加视图的时候会有重叠的现象.例如,UITableV ...

  2. IOS中UITableViewCell的重用机制原理

    创建UITableViewController子类的实例后,IDE生成的代码中有如下段落: - (UITableViewCell *)tableView:(UITableView *)tableVie ...

  3. UIScrollView的重用机制的理解[转]

    UIScrollView的重用机制的理解 UIScrollView的重用机制的理解.大家都知道这个UIScrollView.UItableVIew是继承UIScrollView的UItableVIew ...

  4. iOS开发-自己定义重用机制给ScrollerView加入子视图

    iOS开发-自己定义重用机制给ScrollerView加入子视图 事实上这个问题我非常早就想过,仅仅是没有通过去写程序实现,昨天有人提起,我就巧了一下 不知道大家打印郭tableview:cellfo ...

  5. iOS开发之--TableViewCell重用机制避免重复显示问题

    常规配置如下 当超过tableView显示的范围的时候 后面显示的内容将会和前面重复 // 这样配置的话超过页面显示的内容会重复出现 - (UITableViewCell *)tableView:(U ...

  6. IOS之TableViewCell重用机制避免重复显示问题

    常规配置如下 当超过tableView显示的范围的时候 后面显示的内容将会和前面重复. 1 // 这样配置的话超过页面显示的内容会重复出现2 - (UITableViewCell *)tableVie ...

  7. iOS tableviewcell重用机制避免重复显示

    tableviewcell常规配置如下 当超过tableView显示的范围的时候 后面显示的内容将会和前面重复 一般避免重复显示有3种做法: 1.去掉cell的重用机制 2.让每个cell都拥有一个对 ...

  8. UITableviewcell重用机制以及解决重绘出现的重叠现象

    2019独角兽企业重金招聘Python工程师标准>>> UITableviewcell重用机制以及解决重绘出现的重叠现象 重点1.删除子控件 重点2.重新分配控件 该方法是自定义创建 ...

  9. UITableViewCell中cell重用机制导致内容重复的方法

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

最新文章

  1. 回顾2018——区块链行业十大关键词
  2. 第四章:滚动堆栈(1)
  3. 如何改变cmd的编码格式?
  4. 爱因斯坦:量子物理与抽象数学(广义)
  5. Oracle笔记:备份还原
  6. springboot引入外部yml配置文件
  7. SeaJS项目完整实例【转】
  8. 【漏洞复现】PHPmyadmin 4.8.1后台Getshell新姿势
  9. Linux 学习作业:认识bash shell
  10. 软件项目管理案例教程课后答案
  11. 通俗易懂的LDA模型
  12. js中this指向学习总结
  13. 【每日随笔】2021 年终总结 ( 学习和博客 | 技术学习方向 | 专业学习方向 | 写博客的技巧总结 | 工作成果 | 2022 年展望及职业规划 | 对 CSDN 的建议和期望 )
  14. Day124.分布式事务:Seata、2PC两段式、代码补偿TCC、本地消息表、MQ事物消息
  15. x265-1.7版本-encoder/dpb.cpp注释
  16. Windows驱动开发WDM (1) - 基本结构
  17. 知乎爬虫与数据分析(二)pandas+pyecharts数据可视化分析篇(上)
  18. 查询年龄不大于 20 岁的教师所教的所有课程的课程名(Lintcode刷题)
  19. 互信息介绍及MATLAB代码实现
  20. 生物-大脑极限:大脑极限

热门文章

  1. 卡尔曼滤波+20201205
  2. java结账_java结账系统
  3. autojs海贼王之家免root脚本
  4. 传智播客开课的第二天
  5. javascript动态生成按钮并绑定点击事件
  6. 一 HTML概述,网站首页案例及其知识点
  7. Matlab学习总结
  8. 为防止失联......
  9. ofdm 迭代限幅 matlab,ofdm限幅法matlab的程序
  10. 朴素贝叶斯算法原理、代码实现原理、以及鸢尾花分类代码实现(详细代码原理讲解)