美文网首页
UITableView 删除cell crash问题

UITableView 删除cell crash问题

作者: Seas | 来源:发表于2016-08-04 13:17 被阅读993次

As you know, 动态删除TableView cell的方法为:

[weakSelf.dataSource removeObjectAtIndex:indexPath.row]; [tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];

即先删数据源再在Updates内部删除row
以上代码在方法

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

是没有问题的。
有问题的是需要点击cell内部按钮,在cell方法中使用删除方法时,比如使用cell赋block的方式

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
...
__weak typeof(self) weakSelf = self;
        NSLog(@"删除1:%ld",(long)indexPath.row);
        [cell setTapDeleteBlock:^(UIButton *btn) {
            NSLog(@"删除2:%ld",(long)indexPath.row);
            [weakSelf.dataSource removeObjectAtIndex:indexPath.row];
            [tableView beginUpdates];
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView endUpdates];
            NSLog(@"剩余:%ld",[tableView numberOfRowsInSection:2]);
        }];
...
}

假设当前数据源中有两条记录,倒叙删除cell(先删第二条,再删第一条),以上的log打印为:

删除1:1
删除2:1
剩余:1
删除2:0
剩余:0

并没有问题,但如果正序删除,log打印为:

删除1:1
删除2:1
剩余:1
删除2:1

crash于[weakSelf.dataSource removeObjectAtIndex:indexPath.row];
很简单,因为dataSource中的[1]已经删除,只有1条数据了。
同时,在方法:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"section:%ld row:%ld", indexPath.section, indexPath.row);

打印当前仅存的cell信息,显示:

section:2 row:0

row已经为0。

问题:

删除一个cell后,numberOfRowsInSectiondidSelectRowAtIndexPath方法中row已经变为0,而cellForRowAtIndexPath方法依然为1。因此在继续使用index.row去删除数据源中的元素时,引起crash

解决方法:
  1. 通过所点击的button获取正常的IndexPath
UITableViewCell *cell = (UITableViewCell *)[[btn superview] superview];
NSIndexPath *indexPath = [weakSelf.customTableView indexPathForCell:cell];
  1. 删除cell后,刷新section
[tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationNone];

这种方法简单直接。但是如果当前只有一个section,这种方法与[tableView reloadData],没有区别,使用动态删除也就没有意义。

相关文章

网友评论

      本文标题:UITableView 删除cell crash问题

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