uiTableView在删除单元格时第二次崩溃

时间:2012-08-28 17:29:26

标签: iphone ios ipad uitableview

我是iPhone的新手,我试图从我的UITableView中删除一个单元格,第一次删除得很好,但第二次它给了我以下错误:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', 
reason: 'Invalid update: invalid number of rows in section 0.  The number of rows 
contained in an existing section after the update (3) must be equal to the number 
of rows contained in that section before the update (3), plus or minus the number 
of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or 
minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

这是我的表格代码:

- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
Book_own *temp= (Book_own *)[self.books objectAtIndex:indexPath.row];

if (editingStyle == UITableViewCellEditingStyleDelete) {
    // Delete the row from the data source

    [books removeObjectAtIndex:indexPath.row];

    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

    isDeleted = @"true";
    deletedBook_id = temp.bo_id;

    [self viewDidLoad];

}

else if (editingStyle == UITableViewCellEditingStyleInsert) {
    // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}  

}


 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 2;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.

NSDictionary *dictionary = [listOfItems objectAtIndex:section];
NSArray *array = [dictionary objectForKey:@"myBooks"];
return [array count];
}
在ViewDidLoad中我写了以下代码:

NSDictionary *mbooks = [NSDictionary dictionaryWithObject:books forKey:@"myBooks"];

NSDictionary *mgroups = [NSDictionary dictionaryWithObject:filteredParts forKey:@"myBooks"];
listOfItems = [[NSMutableArray alloc] init];

[listOfItems addObject:mbooks];
[listOfItems addObject:mgroups];

谁能告诉我如何解决这个问题? 提前谢谢。

4 个答案:

答案 0 :(得分:1)

如果我正确读取您的代码,您的数据源是listOfItems。您应该从表数据源中删除该行。一般规则是,当您向UITableView删除或添加项目时,必须更新数据源。

[listOfItemsremoveObjectAtIndex:indexPath.row];

答案 1 :(得分:1)

当您允许多重删除时,您要么不删除该项目,要么只删除一个项目。您可以通过检查是否真的删除如下所示进行调整,或者如果不是,则重新加载数据:

// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        BOOL success = [self removeFile:indexPath];
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        if (!success) [tableView reloadData];
    }
}

然后,此方法删除数据源项(它来自我自己的项目,因此应调整名称:

-(BOOL) removeFile:(NSIndexPath *)indexPath{
    // Removes from the datasource and the filesystem
    NSURL *fileURL = [self.dataSource objectAtIndex:indexPath.row];
    NSError *error;
    BOOL success = [[NSFileManager defaultManager] removeItemAtURL:fileURL error:&error];
    if (success) {
        [self.dataSource removeObjectAtIndex:indexPath.row];
    } else {
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error" message:[error localizedDescription] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
        [alert show];
        [alert release];
        [self.dataSource removeObjectAtIndex:indexPath.row];
    }
    return success;
}

答案 2 :(得分:0)

首先,不要调用[self viewDidLoad];不应手动调用此方法。

我认为你没有在表视图中调用update方法。这可能会解决您的问题:

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

编辑:您还需要更仔细地查看代码。您正在直接从indexPath的行中删除数据源数组中的记录,考虑到tableView有两个部分,这可能会有问题。

答案 3 :(得分:0)

错误表示删除后应该减少1行。它失败了,因为数据源代码报告模型的方式不一致。

看看你如何回答numberOfRowsInSection。我认为,正确地,首先选择部分索引所代表的数组,然后回答该数组的计数。

同样的逻辑必须适用于删除。您从中删除的数组需要是indexPath.section指示的数组。考虑一下:

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

    // the array you manipulate here must be the same array you use to count
    // number of rows, and the same you use to render rowAtIndexPath

    NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
    NSArray *array = [dictionary objectForKey:@"myBooks"];

    // in order to be edited, it must be mutable
    // you can do that on the fly here, or set it up as mutable
    // let's make it temporarily mutable here:
    NSMutableArray *mutableCopy = [array mutableCopy];

    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [mutableCopy removeObjectAtIndex:indexPath.row];

        // if it's setup mutable, you won't need to replace the immutable copy in the dictionary.
        // but we just made a copy, so we have to replace the original
        [listOfItems replaceObjectAtIndex:indexPath.section withObject:[NSArray arrayWithArray:mutableCopy]];

        // and so on