有个信用卡还款列表删除导致索引错乱,展示出来的效果是,用的系统自带的删除功能 ,左滑第一行,第二行出现红色删除按钮,然后左滑第二行的时候第一行又出现红色删除按钮。断点跟踪索引没错,想解绑的的卡也没错,但是页面显示让人难堪。 以为是偶然的 ,上生产的时候产品又点了下,每次同一个手法,必现,测试手法如下: "是两张卡情况下,解绑一张卡,然后再绑刚才解绑的这张卡,然后后面卡bing成功了,直到确认还款,回退两步到卡列表。出现这个情况.但是从app里面信用卡还款点过来(等于是重新创建),就正常了。"
代码如下:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleDelete;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle==UITableViewCellEditingStyleDelete) {
NSDictionary *para = @{@"application":@"UpDelCreditCard.Req",
@"userId":self.manage.userId,
@"phone":self.manage.phone,
@"accNo":_dataArray[indexPath.row][@"accountNo"]
};
[self.mRequest requestWithDictionary:para completion:^(BOOL success, id responseData) {
if (success) {
[_dataArray removeObjectAtIndex:indexPath.row];
[_mTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:indexPath.row inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[self showToast:@"解绑成功"];
}
}];
}
}
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
return @"删除";
}
从上到下看,几乎没错,网上千篇一律也是这样的博客。可以出现问题就是错乱。后来脑子乱了,感觉好像是苹果系统删除的坑,之前做的是点击,弹出alert提示,删除某一行,没出现问题。现在唯一的区别就是用了系统的左滑。无奈之下,跟有安全感的楠哥说了下。
第二天要了账号和产品的登录密码,给楠哥复现和跟踪,不到一小时,楠哥发了个截图,说没问题了。截图如下:
只改了一句话,加了个reloadData就好了,太神奇了,其他地方包括逻辑没问题。问了下原因,说是
deleteRowsAtIndexPaths不自动刷新,颠覆了之前删除的手法。
于是研究了下 deleteRowsAtIndexPaths和reloadData 到底差别如何
deleteRowsAtIndexPaths这个是局部刷新,效率高,节省资源。执行deleteRowsAtIndexPaths只会重新执行numberOfRowsInSection方法,而cellForRowAtIndexPath不会重新执行,这使得每个cell的buttontag不变,不会根据删除后的dataSource重新赋值。(严重的有可能导致崩溃)
reloadData简单粗暴,整体刷新,安全性高大上,缺点是
后来试了下 这么写,也是乱的
[_mTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:indexPath.row inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[_mTableView reloadData];//先局部删除刷新,然后整体刷新,结果是NO
所以改写成一句 [_mTableView reloadData]; 就没事,前提是先处理好数组里面的数据,因为列表和数据是绑定的关系。弄不好直接闪退!