@
目录
简述
TableView主要是为了减少内存的使用,其实现效果和scrollView类似,会将一个个的图像保存为多个cell,在cell不显示的时候,将其会受到缓存中,当滑动到可显示的时候,再从缓存中读取出来。
主要变量
_indices 存储可见范围内cell的索引
_vordering 从上到下或者从下到上
_isUsedCellsDirty 排序脏标记
_cellsUsed 存储正在使用的cell
_cellsFreed 存储不显示的cell
主要方法
setVerticalFillOrder
设置cell的排列方式
- 对cell的排列方式重新设置
- 如果cellsUsed不是空的就调用reloadData
reloadData
重新加载数据来刷新视图
- 重置位置
- 遍历cellsUsed中的cell
- 调用回收cell的自定义回调函数
- 将cell放入缓存容器中
- cell的位置索引设为-1
- 从当前容器中移除当前遍历到的cell
- 清理视图内的cell索引
- 清理存储可视范围内cell的容器
- 刷新cell的位置
- 刷新容器的尺寸
- 调用拖动的回调
cellAtIndex
通过idx找到可视范围内的cell
- 遍历找到idx相同的cell并返回
updateCellAtIndex
更新指定idx的cell的信息,在scrollViewDidScroll找到未添加的cell时调用
- 获取视图中的cell个数
- 获取idx对应的cell
- 如果现在的视图中有这个idx的cell,就加入到缓存中并从当前的视图中移除,索引也移除
- 然后从缓存中读入第一个cell,调用setIndexForCell来设置锚点、位置、idx
- 如果cell不在当前的容器中,就加入并且加到cellsUsed和indices中,并且设置需要刷新顺序的脏标记
insertCellAtIndex
在idx出插入新的cell
- 判断idx是否无效
- 获取当前的cell个数
- 尝试获取idx位置上的cell
- 如果有cell,先获取新的cell
- 将原先的和后面的cell一起往后移动一位
- 然后将缓存中的第一个cell插入idx的位置,并设置属性
- 更新更新cell的位置和容器的大小
removeCellAtIndex
移除指定index的cell
- 先获取cell个数,如果是非法值就直接返回
- 从正在使用的cell容器中获取index对应的cell
调用_moveCellOutOfSight方法
- 加入到缓存容器中,从正在使用的cell容器中移除,设置重排序脏标记,从索引中删除,重置cell
- 从父节点容器中删除这个cell
回到移除方法
- 又进行了一次索引移除的操作,这里我觉得是多余的操作,因为在上面的_move方法中已经做了移除索引的操作了
- 刷新cell的位置
- 遍历正在使用的cell容器,将所有的Idx-1
dequeueCell
获取缓存中第一个cell,并从缓存中移除
获取、retain、erase、autorelease
_addCellIfNecessary
将cell添加到当前容器
- 如果cell的父节点不是当前的容器就添加到现在的容器中
- 将cell加入到cellUsed中
- 将cell的idx加入到indices中
- 添加排序脏标记
_updateContentSize
- 获取cell的个数
- 如果cell的个数大于0,判断滑动的方向,设置不同的大小
- 如果现在设置的滑动方向和初始的滑动方向不一样,重新设置容器的偏移和oldDirection
_offsetFromIndex
调用__offsetFromIndex
- 根据滑动方向对容器的偏移重新设置
回到_offsetFromIndex
- 获取cell的尺寸
- 如果排列顺序是从上到下就对上面最后一个位置留出一个空间位置用来下一次添加
_indexFromOffset
- 获取最大的index
- 如果排列顺序是从上到下就对上面最后一个位置留出一个空间位置用来下一次添加
__indexFromOffset
- 获取cell的个数并减1作为索引
- 对不同拖动方向的设置要查找的offset
- 如果high >= low,获取中间的index,获取index两边的cell并从两边向中间遍历
- 符合if的条件了就返回找到的index
回到函数
- 如果index不等于-1
- index只会是等于0或者大于0的,获取它
- 如果是超限了,就设置成-1
- 最后返回得到的index
scrollViewDidScroll
- 获取已显示的cell个数
- 判断是否有脏标记,有就取消标记并排序
- 根据不同的排列方式设置偏移量
- 获取第一个和最后一个可显示的cell的index,下面的代码会用到,如果第一个或者最后一个的index是-1,表示是占位空间,则将idx设为-1
- 测试代码下面的两个if用来将不在显示范围内的cell移入缓存中
- 最后调用代理方法来调用scrollViewDidScroll来使用回调方法
触摸各阶段的回调方法
onTouchEnded
onTouchBegan
onTouchMoved
onTouchCancelled
都是先调用继承的scrollView中的触摸回调,然后再执行TableView中的逻辑,用来处理偏移和内存的问题