本文转载至  http://www.cocoachina.com/bbs/read.php?tid=299773

基本原理是通过缓存每个cell的高度,当tableview回调delegate的heightForRowAtIndexPath的时候,省去了计算cell高度计算,极大的提高了tableview的滑动体验。

因为 heightForRowAtIndexPath这个接口会在reloadData的时候,每个cell都会调用一次,同时滚动tableview的时候,cell从不可见到可见区域也会被调用一次heightForRowAtIndexPath,所以这个API的调用是很频繁的。由于每个cell的高度是动态的,所以每次要做高度计算,都要重新layout一遍,然后得出高度,这块计算量是比较大的。sunny通过将每个cell的计算好的高度缓存起来,下次获取相同位置cell的高度的时候,直接返回缓存的高度。

同时,当第一次reloadData,或者cell的行数发生变化(增减行,section) ,会先在tableview不处于滚动状态的时候异步计算那些没有被计算过的cell的高度,做预缓存,这块非常赞。就是使用者需要小心,由于这块是异步的, tableview delegate有可能会在预缓存计算的时候不存在了,导致程序崩溃,所以使用者在tableview需要析构的时候,在对应的tableview controller的dealloc中讲self.tableview.delegate = nil;,确保delegate后续不会是一个脏对象。

fd_heightForCellWithIdentifier: cacheByIndexPath: configuration: 

  1. 如果没有打开预缓存开关,则打开该开关,然后异步做一遍预缓存行高计算
  2. 如果缓存了改行的高度则返回行高
  3. 如果么有缓存,则计算行高fd_heightForCellWithIdentifier: configuration,缓存行高并返回

fd_heightForCellWithIdentifier: configuration

  1. 首先获取针对这个identifier类型的模板cell,sunny为每一个类型cell都缓存了一个模板cell,这块我还不明白为什么要这么做,为什么不直接用系统dequeue的重用cell来做?
  2. 将需要计算高度的cell数据填充到这个template cell,然后就可以计算cell高度了
  3. 计算tableview.contentView的真实宽度。
    1. 如果有定制accessoryView,则去除这个宽度
    2. 如果有系统accessoryView展示,则去除对应的宽度。
  4. 检查是否是否是自动布局,判断是否自动布局的标准是contentView本身至少存在一个约束。所以我们在CustomCell做约束的时候,需要至少指定contentView的一个约束。
  5. 如果是自动布局,则将contentView的宽度约束添加进去,这样做的目的是让UILabel之类的内容可能多行的控件适应这个宽度折行(当然前提是我们已经设置好了这些控件的布局约束)。然后调用systemLayoutSizeFittingSize来计算高度。最后移除刚才临时添加的contentView宽度约束。
  6. 如果是绝对布局,则custom cell要重写sizeThatFits接口自己提供行高计算。如果没有重写,则会报错。
  7. 如果存在分割线,则添加1px的高度。因为CGSize是基于point,所以高度计算是 1/[UISscreen mainScreen].scale
  8. 返回计算好的高度。

UITableView+FDTemplateLayoutCell源码学习笔记的更多相关文章

  1. Underscore.js 源码学习笔记(下)

    上接 Underscore.js 源码学习笔记(上) === 756 行开始 函数部分. var executeBound = function(sourceFunc, boundFunc, cont ...

  2. Underscore.js 源码学习笔记(上)

    版本 Underscore.js 1.9.1 一共 1693 行.注释我就删了,太长了… 整体是一个 (function() {...}());  这样的东西,我们应该知道这是一个 IIFE(立即执行 ...

  3. AXI_LITE源码学习笔记

    AXI_LITE源码学习笔记 1. axi_awready信号的产生 准备接收写地址信号 // Implement axi_awready generation // axi_awready is a ...

  4. Hadoop源码学习笔记(6)——从ls命令一路解剖

    Hadoop源码学习笔记(6) ——从ls命令一路解剖 Hadoop几个模块的程序我们大致有了点了解,现在我们得细看一下这个程序是如何处理命令的. 我们就从原头开始,然后一步步追查. 我们先选中ls命 ...

  5. Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构

    Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构 之前我们简要的看过了DataNode的main函数以及整个类的大至,现在结合前面我们研究的线程和RPC,则可以进一步 ...

  6. Hadoop源码学习笔记(4) ——Socket到RPC调用

    Hadoop源码学习笔记(4) ——Socket到RPC调用 Hadoop是一个分布式程序,分布在多台机器上运行,事必会涉及到网络编程.那这里如何让网络编程变得简单.透明的呢? 网络编程中,首先我们要 ...

  7. Hadoop源码学习笔记(3) ——初览DataNode及学习线程

    Hadoop源码学习笔记(3) ——初览DataNode及学习线程 进入了main函数,我们走出了第一步,接下来看看再怎么走: public class DataNode extends Config ...

  8. Hadoop源码学习笔记(2) ——进入main函数打印包信息

    Hadoop源码学习笔记(2) ——进入main函数打印包信息 找到了main函数,也建立了快速启动的方法,然后我们就进去看一看. 进入NameNode和DataNode的主函数后,发现形式差不多: ...

  9. Hadoop源码学习笔记(1) ——第二季开始——找到Main函数及读一读Configure类

    Hadoop源码学习笔记(1) ——找到Main函数及读一读Configure类 前面在第一季中,我们简单地研究了下Hadoop是什么,怎么用.在这开源的大牛作品的诱惑下,接下来我们要研究一下它是如何 ...

随机推荐

  1. Numpy 的ndarray

    创建ndarray 使用array函数 创建一维数组 创建二维数组 并查看有几个列表,每个列表有几个值  查看类型 生成全是0的或者全是1的 具体方法作用

  2. 数据规整化:pandas 求合并数据集(交集并集等)

    数据集的合并或连接运算是通过一个或多个键将行链接起来的.这些运算是关系型数据库的核心.pandas的merge函数是对数据应用这些算法的这样切入点. 默认是交集, inner连接 列名不同可以分别指定 ...

  3. SpringBoot系列十二:SpringBoot整合 Shiro

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合 Shiro 2.具体内容 Shiro 是现在最为流行的权限认证开发框架,与它起名的只有最初 ...

  4. android http json请求3种不同写法

    第一种: public static String invoke() {        String result = null;        try {             final Str ...

  5. Linux——curl(转)

    先介绍curl工具的使用,在其他文章中介绍如何使用curl发送Identity API linux curl是一个利用URL规则在命令行下工作的文件传输工具.它支持文件的上传和下载,所以是综合传输工具 ...

  6. Oracle备份与恢复介绍(物理备份与逻辑备份) 分类: Oracle 2015-07-27 22:59 15人阅读 评论(0) 收藏

    算是挺全的了,有命令有真相 原文链接:http://blog.chinaunix.net/uid-354915-id-3525989.html 一.Oracle备份方式分类: Oracle有两类备份方 ...

  7. ELK filter过滤器来收集Nginx日志

    前面已经有ELK-Redis的安装,此处只讲在不改变日志格式的情况下收集Nginx日志. 1.Nginx端的日志格式设置如下: log_format access '$remote_addr - $r ...

  8. MYSQL之You can't specify target table for update in FROM clause解决办法

    mysql中You can't specify target table for update in FROM clause错误的意思是说,不能先select出同一表中的某些值,再update这个表( ...

  9. js 历史

    原文http://javascript.ruanyifeng.com/introduction/history.html JavaScript的诞生 JavaScript 因为互联网而生,紧随着浏览器 ...

  10. 1. BeeGo 介绍与项目的创建,启动

    简介 BeeGo是一个快速开发Go而应用的HTTP框架,他可以用来快速开发API,web以及后端服务等各种应用,是一个restful 的框架,主要涉及灵感来源于tornado,sinatr和flask ...