iOS UITableView崩溃bug解析

1.崩溃bug之UITableView+FDTemplateLayoutCell:

      最近在项目开发中,在使用UITableView时,程序直接崩溃。当然项目中,使用到 UITableView+FDTemplateLayoutCell来缓存tableView高度。(git地址:FDtemplateLayoutCell地址)。崩溃日志如下:

图片1

FDTemplateLayoutCell崩溃信息位置:

iOS UITableView崩溃bug解析_第1张图片
图2

当看到这个日志后,立马就知道是因为XYBugTableCell没有注册上才导致崩溃的,于是就查找在加载VC的时候 到底有没有注册Cell。

iOS UITableView崩溃bug解析_第2张图片
图3

发现cell也注册了。再看下cell注册也没有问题的。但是为啥就会崩溃呢。于是开始查找原因。首先,难道是FDTemplateLayoutCell库的问题?为了验证这个问题,先不用这个库,直接在返回高度固定高度。

iOS UITableView崩溃bug解析_第3张图片
图4

发现直接返回固定高度,程序一切运行OK。这样看来真的是这个库有问题了呢。oh my god,我怎么有点不相信了呢。在项目中,其他的地方也用到这个呢,都没有问题。于是,找一个正常运行的VC来作对比。两个VC中,tableView写法一样的,但唯独一点不同的是:

iOS UITableView崩溃bug解析_第4张图片
图5

可以看出,唯一不同的是,设置tableFooterView的位置。于是,像上图一样,改下设置tableFooterView的位置来验证下。果然,程序神一般的运行成功了。好奇怪,为啥会有这种结果呢?难道是偶然事件?于是,在重新设置到原来的位置,程序还是崩溃。反复验证几次,真的是设置tableFooterView的位置不当,而造成的程序崩溃,并不是FDTemplateLayoutCell的原因。

虽然崩溃解决了,但是原因在哪里呢?当给tableView设置tableFooterView的发生了什么?于是,来打断点测试下。在tableView的UITableViewDelegate,UITableViewDataSource代理中,打上断点,如下:

iOS UITableView崩溃bug解析_第5张图片
图6

运行程序,正常走到23断点处,继续放开23断点。此时,会发现程序不会直接走25断点,而是走31、35、39断点,也是tableView的代理方法。这一点说明,在设置tableFooterView的时候,系统会自动调用reload方法,去刷新tableView。因此,当走到39断点时,FDTemplateLayoutCell会去根据标识符获取cell,而此刻还没有走到25断点处,所以tableView的cell还没有注册上,此刻去获取cell,就会报错,导致程序的崩溃。

解决方案:先注册cell,在设置tableFooterView。

2.崩溃bug之xib(estimatedRowHeight):

       相信现在好多开发者都用xib开发,但是有时候xib开发遇到的bug,真的让人无从下手。主要还没有崩溃日志。在项目开发中,就遇到这么一个问题。在xib中,直接添加一个tableView,拉属性等等操作。然后运行程序,一切OK(此刻是iOS11系统)。说明在iOS11系统下,没有问题。然后切换到iOS10系统,运行程序,发现直接崩溃,崩溃日志如下:

图7

直接崩溃到main函数里。控制台也没有崩溃信息。难道xib加载tableView和系统有关?在切换到iOS11系统,依旧没有问题。有点郁闷。于是,用纯代码写tableView的初始化来验证下。发现不论在iOS10 还是iOS11系统,都没有问题,运行一切OK。这就奇怪了,看来真的是xib初始化tableView的问题。

   调试工程,返回到初始xib加载tableView的状态,iOS11不用验证了,直接在iOS10系统下,运行,依旧崩溃。难道是xib加载tableView的时候都默认设置了什么吗?于是在xib中,查看tableView的一些设置,发现一个问题:

iOS UITableView崩溃bug解析_第6张图片
图8

在xib 加载tableView的时候,会默认选中estimatedRowHeight,如上图(图8)。会不会是这两个默认设置的原因?于是,取消默认选中。然后运行程序(iOS11和iOS10系统),居然程序运行正常,没一点毛病。在勾选上,运行程序崩溃。看来真的是它的原因造成的。但是为啥系统默认的在iOS10会崩溃呢?按道理来说 不应该的呢。难道是工程里面有别的设置导致的?

     为了探讨这个问题,又重新创建一个全新的工程,就初始化一个xib和tableView。所有xib设置和上面工程一样,然后运行程序,发现程序运行居然正常!!!(iOS11、iOS10系统)都OK。这说明xib上tableView默认勾选也没有问题呀。那么问题究竟出在什么地方?

     在项目中,默认选中estimatedRowHeight在iOS10系统下 就会崩溃,是不是在工程里面也设置这个属性,导致冲突的?果不其然,为适配iPhone X时,在项目中加入了如下代码:

图9

     为啥加入这几行代码就会崩溃?看下苹果怎么定义的吧。

图10

是不是瞬间明白了。因此,在iOS11 系统下,程序没有崩溃。在iOS10系统下,由于设置了全局的tableView的estimatedRowHeight属性,而导致程序崩溃。

解决方案:注释掉图9的代码,或者加个判断,只在iOS11下面设置。或者取消图8xib系统默认勾选。

如有问题,欢迎指正。Demo地址:测试Demo 

你可能感兴趣的:(iOS UITableView崩溃bug解析)