1

私は NSFetchedResultsController を使用してテーブルビューにデータを入力し、すべて問題ありません(追加、削除...).しかし、テーブルビューから最後の行を削除しようとすると(タブビューに1行しかない場合)、アプリは以下のログでクラッシュします:

 *** 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)

私が見る限り、デリゲート メソッドがテーブルビューをリロードしようとしたときにオブジェクトを削除した後、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;
    }
}
4

1 に答える 1

0

数日後、この問題を解決する別のロジックを決定しました。最初にfetchedObjectsonのカウントを制御しますfetchedResultsController。カウントが 1 より大きい場合は、削除を呼び出してデリゲートをデータベースに保存しますが、カウントが 1 の場合は、別の viewController にプッシュするだけです。そのVCでも、新しいメッセージが来るまで、このView Controllerに戻るNavigation Controllerを無効にします。そして、新しいメッセージが来ると、まずエンティティのオブジェクトを削除してから、メッセージを追加します..

ここにいくつかの擬似コードとアルゴリズムがあります:

     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 に答える