无法从fetchedResultsController中删除最后一个对象

时间:2012-08-03 13:37:06

标签: ios uitableview core-data nsfetchedresultscontroller

我使用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为null会导致崩溃..如何处理这个问题?提前致谢

编辑 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;
    }
}

1 个答案:

答案 0 :(得分:0)

几天后,我决定采用不同的逻辑来解决这个问题。我首先控制fetchedObjectsfetchedResultsController的计数,如果计数大于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");
         }
     } 

}