美文网首页
7 tableview

7 tableview

作者: 哈库呐玛塔塔__ | 来源:发表于2020-05-13 02:36 被阅读0次

    1.dalegate和datasource的执行顺序和执行次数

    numberOfSectionsInTableView

    tableView:heightForHeaderInSection   //这里这个方法连续调用了两次

    tableView:heightForFooterInSection   //这里这个方法也连续调用了两次

    tableView:numberOfRowsInSection

    上边这个顺序重复了四次后开始调用获取cell和cell高度的方法

    tableView:cellForRowAtIndexPath

    tableView:heightForRowAtIndexPath

    先获取cell,再计算高度

    2.预算高度是干嘛的,估算不准会出现什么情况

    因为UITableview是个UIScrollView,加载时需要先知道自己的contentSize后,再根据自己的bounds,contentInset,contentOffSet,等属性共同决定,是否可以滑动,以及滚动条的长度。而UITableView一开始并不知道自己有多少内容,需要通过dalegate,dataSource的方法调用才能知道,这样就造成他在加载的时候就浪费了多余的计算在屏幕显示外的cell上了。

    设置的估算高度如果不准,因为滑动的时候实时更新着cell的高度,那么contentSize也就会跟着实时变化,这时候滚动条就会出现肉眼可见的突然变化,甚至是跳跃。

    3.为何tableview在reloadData后要先计算高度

    数据源变更后,需要将所有显示的UITableViewCell和未显示可复用的UITableViewCell全部从父视图移除,重新创建,重新创建肯定需要先计算高度,来重新设置contentSize,因为UIScrollView加载需要知道contentSize。

    4.cell的复用原理。(如何判断cell出去了屏幕)

    _reusableTableCells_visibleCells 

    如何判断当前是否出去了屏幕?

    通过滚动偏移量获取当前显示的bounds ,CGRectMake(0,contentOffset,tableview.width,tableview.height);     获取当前cell的rect  然后相比较.

    5.如何避免tableview的卡顿

    CPU:

    1)缓存高度

    2)cell界面复杂考虑frame布局

    3)复用cell时应尽量避免new出cell中使用的对象,应考虑复用

    4)高度变化不大,考虑预算高度

    5)如果图片过大,要考虑在sdwebimage缓存图片之前将图片压缩

    GPU:尽可能避免离屏渲染

    1)圆角

    2)透明度

    3)阴影

    6.想在tableview reloadData完之后做某些操作的方法

    方法一: [self.tableView reloadData]; 

                    [self.tableView layoutIfNeeded]; 

                    //doSomething

    方法二: [self.tableView reloadData];

                     dispatch_async(dispatch_get_main_queue(), ^{

                        //doSomething

                     });

    7.简述如何实现一个Tableview。 参考了Chameleon源码和本篇文章以及这边文章的注解

    1)首先看初始化方法中三个比较有用的属性。除了做了一些基本属性的初始化之外,还初始化了三个比较重要的属性cachedCells  sections  reusableCells。 然后标记了needsReload。    

    2)然后是调用设置 数据源和代理的方法。我们发现当设置了数据源之后,代码中又一次设置了needsReload的标志。告诉NSRunLoop数据源已经设置好了,需要在下一次循环中使用数据源进行布局。

    _dataSourceHas 和 _dataDelegateHas  是一个用于记录该数据源或者代理实现了哪些方法的结构体,该结构体源码如下:

    其实也可以使用布尔值的属性来表示,但是布尔变量占用的内存大小为一个字节即8byte,但是该结构体用一个byte来记录,大大缩小了占用的内存。

    ?xml version="1.0" encoding="UTF-8"?

    3)接下来看下_setNeedsReload的源码

    其实就是将needsReload标记为yes 然后调用setNeedsLayout方法,之后NSRunloop会在下一次循环中自动调用layoutSubviews方法。

    4)那么UITableview的layoutSubviews方法中到底做了什么?

    5)下面来看看reloadData方法的实现

    其中_updateSectionsCache方法是最重要的一个方法。

    该方法会在调用reloadData方法之后,清除之前缓存的sections信息,然后根据dataSource来计算每一个UITableViewSection的所有信息,包括header的view,title,height,以及section下所有行的总高度rowsHeight,然后将UITableViewSection对象放到_sections数组中进行缓存。这些缓存的数据用于后边对tableview的布局。

    6)最后就是UITableView最核心的方法_layoutTableView。

     _sections中存储的就是UITableViewSection的实例对象,其中每一行的高度存储在了一个数组当中 rowHeights。

    _reusableCells 到底是如何使用的?

    在_layoutTableView方法中对cell进行布局的时候。cell的获取方式有两种,如果在当前可视区域内存在直接从availableCells中获取,如果不存在是通过数据源实现的cellForRowAtIndexPath方法中获取的。

    该方法中通常会调用- (UITableViewCell*)dequeueReusableCellWithIdentifier:(NSString*)identifier方法。那么我们看看该方法的实现。

    相关文章

      网友评论

          本文标题:7 tableview

          本文链接:https://www.haomeiwen.com/subject/kjawnhtx.html