前言
昨天加班,本来顺顺利利的,后来测试拿了一个6P来测,装的是8.4.1的系统,我心说真牛,这么老的系统还留着,测试说,就怕有些用户不更新,就喜欢这个版本.本来也没有什么大不了,可没想到测出来的BUG让我吓了一跳,特此记录一下.
- 1.在8.4.1版本上侧滑没有出现删除按钮
- 2.在8.4.1版本上侧滑之后返回上个界面pop的时候程序闪退(注:进入需要删除的界面之后,如果对表格没有点击操作,没有右滑删除操作,返回上个界面是没有崩溃的,😔,其实这里应该看出来的)
一,首先在最新的版本iOS11上没有出现此类情况,在其他版本应该也没有出现此类情况,不然测试就找我了.
我首先查看了我调用的API是否在iOS8中有没有,
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 1)//new
{
return YES;
}
return NO;
}
-(nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{}
NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED
这个API注明iOS8以后可以使用,在watchOS 中禁用.按道理来说应该没错,但是没有道理可讲,在8上侧滑没有反应.然后我就查了一下,大佬们说这是因为什么balabala,加上
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{}
加上这段代码,什么都不用写,然后就可以了.我试了一下,居然真的可以,真是石乐志.(应该是iOS8中在低版本会先调用这个方法,然后再去走新的方法,不懂)
二,这个Bug就比较鸡贼了,闪退的时候没有崩溃的提示信息,直接到了 main 函数里,搜索的时候,看到大佬说的话,一般直接跳到main函数里的并且不打印任何日志的崩溃应该和内存有关系.谢谢
对了,因为觉得API会影响,所以我把
-(nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{}
注释了,实现了
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle ==UITableViewCellEditingStyleDelete) {
[self removeAction:indexPath.row];//这个方法进行删除数组元素,刷新列表的操作
}
}
接下来要做的事情,通过xcode自带的僵尸方法,检查,怎么打开呢,
请按着command+shift+< ,看截图
第二个方法,开着比不开强,我觉得 可以追踪内存来源
保存后,重新运行程序,再重复之前的操作,bug 出现了,右下角也有打印出日志了,问题如下:
2017-12-25 10:13:05.194 xx宝[1621:124805] *** -[STrustDeviceManagerViewController tableView:canEditRowAtIndexPath:]: message sent to deallocated instance 0x158aedfc0
搜索之后发现,有人早在几年前就遇到了这个问题,一下内容大部分为原文来自
startong的博客
也就是说,tableView:canEditRowAtIndexPath 这个方法有问题,那我就纳闷儿了,这个方法怎么可能会有问题,难怪我之前注释掉了这个方法就没问题了,果然是这里有问题,知道了问题针对它解决掉也就不会是什么难事儿了,我初步怀疑是 return YES 的问题,
于是,我在函数里加了这样几行代码
-
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.bgTableView setEditing:NO];
}
然后再重新运行,重复之前的操作,问题解决了,perfect,,,,
虽然问题解决了,但是还是觉得,canEditRowAtIndex 这个方法应该不会有问题,于是我再 ios 6 的模拟器下运行程序,重复操作没问题(当然注释掉viewWillDisappear 方法),后来到网上找了好多资料,很大神都说可能是苹果自身的问题,ios7 才有这个问题,ios6 以及以下不会出现这种问题,
至此,问题得到解决,以上列出了两种解决方案:
1,删掉canEditRowAtIndexPath这个方法不用,不会出问题;(PS : 这个不行,我的表格里面第二个区,才能进行删除操作,而且里面还有一行不能删除,这个方法可以用,但是要看你的实际需求了.)
2,加上上面说的 viewWillDisappear 方法也可以解决问题;但是我个人推荐第二种方法,虽然第一种方法也是可以解决问题的,但是个人还是觉得这两个方法配套使用比较好。
最终总结
最终总结出问题 可能是在 canEditRowAtIndexPath 这个方法里设置了YES然后返回的时候没有把它设置成 NO 所以报错,ios6会自动设置成NO,iOS7 就手动设置成 NO也可以。所以以后无论什么版本,我们都加上viewWillDisappear手动设置 editing 这个属性为NO 这样确保万无一失。
插一句,在iOS9以上没有这个问题,估计是苹果也处理了这个问题,在界面释放的时候,自动设置为NO,所以能升级就赶紧升级,不要让程序猿痛苦了.
如果对你有用,请为我点个赞,留个念.谢谢了