TableView的重用机制,为了做到显示和数据分离, tableView的实现并且不是为每个数据项创建一个tableCell。而是只创建屏幕可显示最大个数的cell,然后重复使用这些cell,对cell做单独的显示配置,来达到既不影响显示效果,又能充分节约内容的目的。下面简要分析一下它的实现原理。

Tableview加载卡顿问题

tableView 滑动卡的问题主要是因为:从缓存中或者是从本地读取图片给UIImage的时候耗费的时间。需要把下面的两句话放到子线程里面:

  1. NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]]; //得到图像数据
    UIImage *image = [UIImage imageWithData:imgData];

把UIImage赋值给图片的时候在主线程。

子线程不能更新UI 所有的UI跟新都是主线程执行了。手指滑动屏幕了。或者屏幕的某个方法执行了。

子线程里面加入NSTimer 的时候需要 手动添加NSRunloop   否则不能循环。

单利里面添加 NSMutableArray 的时候,防止多个地方对它同时便利和修改的话,需要加原子属性。并且用strong,,,并且写一个遍历和修改的方法。加上锁。   Lock   UnLock

重用实现分析:

  查看UITableView头文件,会找到NSMutableArray*  visiableCells,和NSMutableDictnery* reusableTableCells两个结构。visiableCells内保存当前显示的cells,reusableTableCells保存可重用的cells。

  TableView显示之初,reusableTableCells为空,那么tableView dequeueReusableCellWithIdentifier:CellIdentifier返回nil。开始的cell都是通过[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]来创建,而且cellForRowAtIndexPath只是调用最大显示cell数的次数。

  比如:有100条数据,iPhone一屏最多显示10个cell。程序最开始显示TableView的情况是:

  1. 用[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]创建10次cell,并给cell指定同样的重用标识(当然,可以为不同显示类型的cell指定不同的标识)。并且10个cell全部都加入到visiableCells数组,reusableTableCells为空。

  2. 向下拖动tableView,当cell1完全移出屏幕,并且cell11(它也是alloc出来的,原因同上)完全显示出来的时候。cell11加入到visiableCells,cell1移出visiableCells,cell1加入到reusableTableCells。

  3. 接着向下拖动tableView,因为reusableTableCells中已经有值,所以,当需要显示新的cell,cellForRowAtIndexPath再次被调用的时候,tableView dequeueReusableCellWithIdentifier:CellIdentifier,返回cell1。cell1加入到visiableCells,cell1移出reusableTableCells;cell2移出visiableCells,cell2加入到reusableTableCells。之后再需要显示的Cell就可以正常重用了。

  所以整个过程并不难理解,但需要注意正是因为这样的原因:配置Cell的时候一定要注意,对取出的重用的cell做重新赋值,不要遗留老数据。

一些情况:

  使用过程中,我注意到,并不是只有拖动超出屏幕的时候才会更新reusableTableCells表,还有:

  1. reloadData,这种情况比较特殊。一般是部分数据发生变化,需要重新刷新cell显示的内容时调用。在cellForRowAtIndexPath调用中,所有cell都是重用的。我估计reloadData调用后,把visiableCells中所有cell移入reusableTableCells,visiableCells清空。cellForRowAtIndexPath调用后,再把reuse的cell从reusableTableCells取出来,放入到visiableCells。

  2. reloadRowsAtIndex,刷新指定的IndexPath。如果调用时reusableTableCells为空,那么cellForRowAtIndexPath调用后,是新创建cell,新的cell加入到visiableCells。老的cell移出visiableCells,加入到reusableTableCells。于是,之后的刷新就有cell做reuse了。

注意:

1-重取出来的cell是有可能已经捆绑过数据或者加过子视图的,所以,如果有必要,要清除数据(比如textlabel的text)和remove掉add过的子视图(使用tag)。
2-这样设计的目的是为了避免频繁的 alloc和delloc cell对象而已,没有多复杂。
3-设计的关键是实现cell和数据的完全分离

重点:避免重用机制出错

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

2.为每个cell指定不同的重用标识符(reuseIdentifier)来解决。重用机制是根据相同的标识符来重用cell的,标识符不同的cell不能彼此重用。

NSString *identifier = [NSString stringWithFormat:@"TimeLineCell%d%d",indexPath.section,indexPath.row];  

3.删除重用的cell的所有子视图,从而得到一个没有特殊格式的cell,供其他cell重用。

  1. if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }
    else
    {
    //删除cell的所有子视图
    while ([cell.contentView.subviews lastObject] != nil)
    {
    [(UIView*)[cell.contentView.subviews lastObject] removeFromSuperview];
    }
    }

iOS tableview和 Collection复用机制的更多相关文章

  1. tableView中cell的复用机制

    TableView的重用机制,为了做到显示和数据分离,IOS tableView的实现并且不是为每个数据项创建一个tableCell.而是只创建屏幕可显示最大个数的cell,然后重复使用这些cell, ...

  2. cell 的复用机制

    一个问题引发的血案,以下是本侦探的探案过程的一部分:以下全部都是转载自别人的博客:http://blog.sina.com.cn/s/blog_9c3c519b01016aqu.html 转自:htt ...

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

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

  4. QF——UITableViewCell性能优化(视图复用机制)

    这几篇博客总结的不错: 点击进入 点击进入 总结起来方案一般有以下几种: 1.不使用透明视图: 2.减少视图的个数: 3.cell复用机制:(重点) 4.图片缓存: 5.网络请求使用非主线程. 6.预 ...

  5. cell的复用机制

    以下全部都是转载自别人的博客:http://blog.sina.com.cn/s/blog_9c3c519b01016aqu.html 转自:http://www.2cto.com/kf/201207 ...

  6. Cell的复用机制问题总结

    创建方式汇总,注册和不注册Cell注册的两种方式 1.tableView registerNib:(nullable UINib *) forCellReuseIdentifier:(nonnull ...

  7. Android学习笔记之ListView复用机制

    PS:满打满算,差不多三个月没写博客了...前一阵忙的不可开交...总算是可以抽出时间研究研究其他事情了... 学习内容: 1.ListView的复用机制 2.ViewHolder的概念 1.List ...

  8. 再谈select, iocp, epoll,kqueue及各种I/O复用机制

    原文:http://blog.csdn.net/shallwake/article/details/5265287 首先,介绍几种常见的I/O模型及其区别,如下: blocking I/O nonbl ...

  9. I/O复用机制概述

    导读 /O多路复用技术通过把多个I/O的阻塞复用到同一个select的阻塞上,从而使得系统在单线程的情况下可以同时处理多个客户端请求.与传统的多线程/多进程模型比,I/O多路复用的最大优势是系统开销小 ...

随机推荐

  1. ORACLE 错误代码提示归集

    有时数据库出现问题,不是每次都有网络可查,所以把所有的ora系列的错误整理出来, 在最没有办法的时候,需要自己来解决,有了这些根据,问题会好办的.虽说对于数据库方面, DBA很强大,他们在遇到错误时, ...

  2. 2715:谁拿了最多奖学金-poj

    总时间限制:  1000ms 内存限制:  65536kB 描述 某校的惯例是在每学期的期末考试之后发放奖学金.发放的奖学金共有五种,获取的条件各自不同: 1) 院士奖学金,每人8000元,期末平均成 ...

  3. 大道至简第一章Java伪代码读后感

    import.java.大道至简.*; //周爱民 import.java.读后感*; public class shawanyia { //1. 编程的精义 while(山没有消失) {if(愚公没 ...

  4. Innodb中的锁

    Innodb中的锁 共享锁和排它锁(Shared and Exclusive Locks)共享锁和排它锁是行级锁,有两种类型的行级锁 共享锁(s lock)允许持有锁的事务对行进行读取操作 排它锁(x ...

  5. Spring Cloud 之 Feign

    新建Spring Boot工程,命名为feign 1.pom.xml添加依赖 <?xml version="1.0" encoding="UTF-8"?& ...

  6. Codeforces 869E The Untended Antiquity

    题意:给定一个网格图,三种操作:1.在(r1,c1,r2,c2)处建围墙.2.删除(r1,c1,r2,c2)处的围墙.3.询问两点是否可达 思路比较巧妙,将围墙内的点赋加一个权值,询问的时候判断两个点 ...

  7. vue-cli 使用小技巧

    1.关闭烦人的eslint 语法检测,在 config 文件夹下 设置: // Use Eslint Loader? // If true, your code will be linted duri ...

  8. IP协议和网络传输中的封装与分用。

    关于七层模型和四层模型可以参考这个:http://www.cnblogs.com/xcywt/p/5027277.html 因为四层模型用的比较多,这里只拿四层模型来分析. 1.四层模型中的最下层是链 ...

  9. NDK开发过程自认为好的一些参考资料

    虽然NDK开发时间很短, 但也接触了一些自认为还不错的资料, 记录下来. 一.首先就说官方文档吧 网上资料好多过时了, 并且有点参差不齐. 所以看官方文档还是很有必要的,我根据我的需求整理了两个的链接 ...

  10. poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)

    题目链接:http://poj.org/problem?id=2299 Description In this problem, you have to analyze a particular so ...