尝试删除单元格和节时,UITableView崩溃

时间:2012-04-22 16:21:20

标签: iphone xcode uitableview crash

我一直致力于创建一个UITableView,其内容从NSUserDefaults对象加载。但是,每当我尝试删除一个单元格/节时,程序就会崩溃并吐出以下内容:

*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1912.3/UITableView.m:1030
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections.  The number of sections contained in the table view after the update (2) must be equal to the number of sections contained in the table view before the update (3), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).

无论我多少读过这个错误并尝试修复它,我都被困在这里过去几个小时。这是我的方法,当用户点击“删除”按钮时调用该方法:

 (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        //[[[NSUserDefaults standardUserDefaults] objectForKey:@"rawArray"] removeObjectAtIndex:indexPath.row];
        //[[[NSUserDefaults standardUserDefaults] objectForKey:@"rawDates"] removeObjectAtIndex:indexPath.row];

        NSMutableArray *rawArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"rawArray"];
        NSMutableArray *rawDates = [[NSUserDefaults standardUserDefaults] objectForKey:@"rawDates"];

        [rawArray removeObjectAtIndex:indexPath.row];
        [rawDates removeObjectAtIndex:indexPath.row];

        [[NSUserDefaults standardUserDefaults] setObject:rawArray forKey:@"rawArray"];
        [[NSUserDefaults standardUserDefaults] setObject:rawDates forKey:@"rawDates"];

        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
        [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationRight];

    }    
}

以下是用于确定行数和单元格数的方法:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return [[[NSUserDefaults standardUserDefaults] arrayForKey:@"rawDates"] count];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{

    return [[[NSUserDefaults standardUserDefaults] arrayForKey:@"rawDates"] objectAtIndex:section];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 1;
}

那里的最后一个方法返回一个,因为到目前为止,我计划每个部分只有一个单元格。感谢您抽出宝贵时间来看看这里,我真的希望您能帮助我! :/

1 个答案:

答案 0 :(得分:14)

查看Batch Insertion, Deletion, and Reloading of Rows and Sections

基本上你需要调用这些方法

- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;

- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation;
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation;
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;

之间的

- (void)beginUpdates;
- (void)endUpdates;

e.g。

[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationRight];
[tableView endUpdates];

您的dataSource还需要在调用endUpdates时反映更改


就个人而言,我喜欢创建一个类别,将基于块的包装器提供给

  1. 阻止我忘记拨打endUpdates
  2. 它允许缩进看起来正确/自动
  3. UITableView

    上的类别
    @interface UITableView (PSAdditions)
    
    - (void)ps_updates:(void (^)(void))updateBlock;
    
    @end
    
    @implementation UITableView (PSAdditions)
    
    - (void)ps_updates:(void (^)(void))updateBlock;
    {
        [self beginUpdates];
        if (updateBlock) { updateBlock(); }
        [self endUpdates];
    }
    

    看起来像这样

    [tableView ps_updates:^{
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
        [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationRight];
    }];