2012-08-28 86 views
0

我是iPhone中的新手,我想从我的UITableView中删除一个单元格,第一次删除的很好,但第二次它给了我以下错误: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]; 

谁能告诉我如何解决这个问题? 在此先感谢。

+3

所以..你在你的表格视图中有3行,你删除了一行,而你**仍然**在你的表格视图中有3行...这就是投诉 – nielsbot

回答

1

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

[listOfItemsremoveObjectAtIndex:indexPath.row]; 
+0

我试过了,但它仍然给我异常:( – user1553381

0

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

我认为你不是调用你的表视图的更新方法。这可能会解决您的问题:

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

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

0

错误提示删除后应该有少一行。它失败是因为数据源代码在报告模型方面不一致。

看看你如何回答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 
+0

listOfItems是一个NSMutableArray而不是NSMutableDictionary – user1553381

+0

没错,编辑。我希望你会在这里看到的关键想法是acces s到你的模型必须是所有数据源方法中indexPath的相同函数。 – danh

+0

我试过了,它给了我以下例外: - [__ NSArrayI objectForKey:]:无法识别的选择器发送到实例0xebe20c0 2012-08-28 21:24:02。782 eBook_App [460:f803] ***由于未捕获的异常'NSInvalidArgumentException',原因:' - [__ NSArrayI objectForKey:]:无法识别的选择器发送到实例 – user1553381

1

正在发生的事情是,你要么不删除项目或只删除一个项目时,你允许multible删除。您可以通过检查它是否真的删除如下调整或重新加载数据,如果没有:

// 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; 
} 
+0

我终止了应用程序但它仍然给我这个例外:( – user1553381

+0

使用NSLog在删除一行后打印出每个部分的项目数量。另外,您是否允许多次删除? –