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. ExtJS+Handler入门显示

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.c ...

  2. _1Python简介 安装及版本检测

    简介 Python是一种面向对象的解释性计算机程序设计语言,由荷兰人Guido von Rossum于1988年的圣诞节发明,第一个公开发行版于1991年. Python崇尚优美.清晰.简单,是一个优 ...

  3. webpack 3.X学习之图片处理

    CSS中图片处理 在src目录下新建一个images目录,把图片放入images文件夹中:在index.html文件中增加一个div标签: /src/index.html: <div id=&q ...

  4. Gluon炼丹(Kaggle 120种狗分类,迁移学习加双模型融合)

    这是在kaggle上的一个练习比赛,使用的是ImageNet数据集的子集. 注意,mxnet版本要高于0.12.1b2017112. 下载数据集. train.zip test.zip labels ...

  5. JAVAFX-5事件总结

    事件监听 在RIA 或者说 桌面客户端gui android 开发中,事件的机制是必须的要学习了解的, 分类处理类型 在Java GUI 和swing中,事件通常通过实现listener的接口函数,并 ...

  6. 比ngx_http_substitutions_filter_module 更强大的替换模块sregex的replace-filter-nginx-module

    之前写过nginx反代替换的教程(传送门),使用了ngx_http_substitutions_filter_module模块.不过这货只能替换同一行,具有局限性-_-# 现在一个更强大的替换模块来了 ...

  7. Numpy数组对象的操作-索引机制、切片和迭代方法

    前几篇博文我写了数组创建和数据运算,现在我们就来看一下数组对象的操作方法.使用索引和切片的方法选择元素,还有如何数组的迭代方法. 一.索引机制 1.一维数组 In [1]: a = np.arange ...

  8. cinder存储节点 后端采用lvm、nfs安装配置

    #cinder存储节点 openstack pike 部署 目录汇总 http://www.cnblogs.com/elvi/p/7613861.html #cinder存储节点 #cinder后端采 ...

  9. golang关于一些新手不注意会出现的小问题

    前言 最近在整理之前写程序,学习时所记录的有道云笔记,发现一些有意思的小点跟大家分享一下.如有错误请大家给指出 一.闭包 defer 闭包(匿名函数) func test(){ i, n := ,; ...

  10. Code Kata:大整数比较大小&大整数四则运算---加减法 javascript实现

    大整数的四则运算已经是老生常谈的问题了.很多的库也已经包含了各种各样的解决方案. 作为练习,我们从最简单的加减法开始. 加减法的核心思路是用倒序数组来模拟一个大数,然后将两个大数的利用竖式进行运算. ...