1

我使用 NSFetchedResultsController 来填充 tableview 并且一切正常(添加、删除 ..).. 但是每当我尝试从 tableview 中删除最后一行时(当 tablview 中只有一行时)应用程序崩溃并显示以下日志:

 *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1914.84/UITableView.m:1037
2012-08-03 16:32:39.667 MackaWithCoreData[793:15503] CoreData: error: Serious application error.  An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:.  Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), 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). with userInfo (null)

据我所见,当委托方法尝试重新加载 tableview 时删除对象后,因为 fetchedResultsController 为空,它会导致崩溃。如何处理这个问题?提前致谢

编辑实现controller controllerDidChangeContent:..。方法如下

 - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{

    switch(type)
    {

        case NSFetchedResultsChangeInsert:
            [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            XLog(@"the row removed from tv");

            break;

        case NSFetchedResultsChangeUpdate:
         // [self configureCell:[self.tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            XLog(@" object deleted from fetchedresultscontroller");

            [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}
4

1 回答 1

0

几天后,我决定用不同的逻辑来解决这个问题。我首先控制fetchedObjectson的计数fetchedResultsController,如果计数大于 1,我调用数据库上的删除和保存委托,但如果计数等于 1,则只需推送到不同的 viewController。在那个 vc 上,我也会禁用导航控制器回到这个视图控制器,直到有新消息出现。当有新消息出现时,我将首先删除实体上的对象,然后添加消息..

这是一些伪代码和算法:

     if ([[self.fetchedResultsController fetchedObjects]count] >1) {
         callDeletionDelegateForDatabase;
      }else{
       declare a viewController object;
       pushToThatVC;
      }

// 关于目标 vc 的类

hide_back_navigation_back_to_theViewControllerYouCameFrom;
     //when a new message comes from web service
     reset Entitiy(the property we need its value)
     show_navigation_Controller_To_theViewControllerOfMessages...

我发布了这个愚蠢的伪代码来帮助面临同样情况的其他人,如果有人知道更好的方法,请写下来。下面是我的代码:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
     if (editingStyle == UITableViewCellEditingStyleDelete) { 
         if ([[self.fetchedResultsController fetchedObjects]count] >1) {

        NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext]; 
          [context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]]; 

        // Save the context. 
        NSError *error = nil; 
        if (![context save:&error]) { 
             /* 
             Replace this implementation with code to handle the error appropriately. 

             abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
             */ 
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
            abort(); 
            } 
         }else {
             BNT_DetailViewController *vc=[BNT_DetailViewController new];
             [self.navigationController pushViewController:vc animated:YES];

             XLog(@"You Cant delete this");
         }
     } 

}
于 2012-08-10T09:17:01.240 回答