【iOS】UITableViewCell的重用问题解决方法

打印 上一主题 下一主题

主题 774|帖子 774|积分 2322

我本身在实验中对cell的重用总结如下:
非自定义Cell和非自定义cell的复用环境一样:

  • 第一次加载创建tableView的时间,是屏幕上最多也表现几行cell就先创建几个cell,此时复用池里什么都没有
  • 开始下滑tableView,刚开始滑动时,由于第一行没有完全滑出屏幕进复用池时,下面的新cell已经表现到屏幕上了,所以下方这个新滑出来的cell就是新创建的cell而不是复用的cell(复用时也得看新加载的cell和复用池中的备用cell有没有同类型的id,没有就不复用),然后接着滑动,第一个cell就完全出屏幕进入复用池了,下面我们接着滑动,接着那个需要新表现出来的cell如果和复用池中我们生存的第一个cell是同种id,如果是就直接拿来复用,如果不是就新创建(判定是否能复用和新创建的操纵都在cell的编辑函数:cellForRowAtIndexPath:中)
  • 上滑tableView和下滑原理基本一致,完全出屏幕的入复用池,需要新加载到屏幕的cell,先看池中有没有同id的cell,有了就复用,没有就创建。
下面我们讲一个使用cell时需要留意的点:
复用时从复用池中取出来的cell可以是已经捆绑过数据或者加过子视图的,所以,如果有必要,要清除数据,好比(label的text)和remove掉add过的子视图(使用tag),否则就有可能造成复用后出现表现的内容不符预期的环境,好比说我们有一个开始创建id为@"test"的cell,我们在执行cell的编辑函数:cellForRowAtIndexPath:中有一个判定分支,符合某种环境时需要在cell上表现一个button,而不符合那种环境的时间就不表现button,而恰恰我们这个cell符合环境,于是就添加了button相关的数据,然后表现出了button,接着我们滑动了tableView,导致我们刚才创建的这个id为@"test"的cell进入了复用池,然后再继续下滑的时间有一个新的id为@"test"的cell需要被加载出来,于是就检察了复用池,发现里面有同id的cell,所以就直接拿来复用了,复用的时间对里面的数据进行了本身的设定,本类好像没什么问题,但是恰恰这个新cell不符合那个要表现button的条件,然后就不会去执行对button添加数据的操纵,我们预想着这个新cell和之前我们创建的id为@"test"的cell的区别就是新的没有button,旧的有button,然后两者其他控件也就是数据内容差别(好比label的text不一样这些),但是实际环境却是这个新创建的cell上面表现的依然存在button,和我们预想的不一致,其原因就是复用时所取出来的旧cell是已经捆绑过数据且加过子视图的,虽然我们新cell创建时没有走对button添加数据的代码,但是由于旧cell走过了,且向button添加的数据都在,所以就导致新cell上面就有一个和旧cell千篇一律的button。
这就是复用中可能存在的一个常见的难搞的问题,但是解决起来实在也非常简单,重点在于:避免重用机制出错
以下有三种方法:(最保举第三种)

  • 重用机制调用的就是dequeueReusableCellWithIdentifier这个方法,方法的意思就是“出列可重用的cell”,因而只要将它换为cellForRowAtIndexPath(只从要更新的cell的那一行取出cell),就可以不使用重用机制,因而问题就可以得到解决,但会浪费一些空间。

  • 为每个cell指定差别的重用标识符(reuseIdentifier)来解决。重用机制是根据雷同的标识符来重用cell的,标识符差别的cell不能相互重用。
  1. NSString *identifier = [NSString stringWithFormat:@"TimeLineCell%d%d",indexPath.section,indexPath.row];
复制代码

  • 在新cell创建走编辑函数:cellForRowAtIndexPath:时,在里面加一段操纵,去remove多余的那个子视图或者清除旧数据

而且依我本人之见,最好使用清除旧数据而不是remove多余的子视图。因为这个正在新建的cell背面也许也会进入主动释放池,而且它到时间也可能会被拿来复用,如果那个复用它的cell刚好需要表现button而这个被复用的cell连button这个视图都没添加到cell上,那直接向button添加数据时步伐就会crash,所以清除所有数据是不错的选择,反正每次执行编辑函数:cellForRowAtIndexPath:时都会为对应行组的cell重新添加那些子视图上的数据(相当于覆写了旧数据),我们只需要在所有的重新添加数据操纵之前讲被复用的cell上子视图的数据全删了就行。
但是如果偏要走remove子视图的方法也不是不行,我们可以巧妙点,从复用池取出来要被复用的cell之后直接重新alloc初始化一下这个被复用的cell,相当于之前清空了本来生存的所有子视图的全部数据,而本来添加到cell上的子视图都还在,只是没有数据不表现罢了,这也是很好的本领。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美食家大橙子

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表