2

validateForInsert と validateForUpdate をオーバーライドする NSManagedObject エンティティがあります。

このメソッドは、私が書いたいくつかのロジックに基づいて、オブジェクトの一貫性に問題がある場合に正しく NO を返します。

このアプリケーションは、NSFetchedResultsController に支えられた従来の uitableview であり、詳細ビュー コントローラーを備えています。

新しいエンティティを追加すると、詳細ビ​​ュー コントローラーが nil objectID でインスタンス化され、ナビゲーション スタックにプッシュされます。詳細コントローラーをポップすると、[context save:&error] が呼び出され、ブレークポイントを配置することで、validateForInsert が NO を返し、includePendingChanges が設定されている場合でも、新しいエンティティを追加すると、フェッチされたデリゲート メソッドが 1 回起動されることがわかりました。いいえ。

詳細コントローラーを再度ポップしようとすると、もちろん保存が再度呼び出され、検証メソッドも呼び出されますが、今回は NSFetchedResultsControllerDelegate は起動されません。

これが正常な動作なのか、それともモデルに何か欠けているのかを知りたいです。

[アップデート]

これは、デリゲート メソッドのブレークポイント後のスタック トレースです。

#0  0x0003e5ba in -[MyTableViewController controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:] at ......
#1  0x011512f9 in -[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:] ()
#2  0x00b46a29 in __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_0 ()
#3  0x01759855 in ___CFXNotificationPost_block_invoke_0 ()
#4  0x01759778 in _CFXNotificationPost ()
#5  0x00a8b19a in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#6  0x0106a673 in -[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] ()
#7  0x01101f5e in -[NSManagedObjectContext(_NSInternalChangeProcessing) _createAndPostChangeNotification:withDeletions:withUpdates:withRefreshes:] ()
#8  0x01065ad3 in -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] ()
#9  0x0106916b in -[NSManagedObjectContext save:] ()
#10 0x00004490 in -[MyAppDelegate saveContext:]

保存がコンテキストで呼び出されても、検証が呼び出されないことがわかります。したがって、フェッチされたコントローラーデリゲートが起動されます。

[更新 2]

特に、関連しているかどうかはわかりません。これにより、controllerDidChangeObject で例外が発生します (常にではありません)。

CoreData: エラー: 重大なアプリケーション エラーです。-controllerDidChangeContent: の呼び出し中に、NSFetchedResultsController のデリゲートから例外がキャッチされました。無効な更新: セクション 0 の行数が無効です。更新後の既存のセクションに含まれる行数 (4) は、更新前にそのセクションに含まれる行数 (3) に、その数をプラスまたはマイナスした値と等しくなければなりません。そのセクションに挿入または削除された行数 (0 挿入、0 削除)、およびそのセクションに移動された、またはそのセクションから移動された行数 (0 移動、0 移動)。userInfo (ヌル)

元のテーブルには実際には3つの行がありますが、オブジェクトがコンテキストで作成されたときにコンテキストがvalidateForメソッドをバイパスするため、行が挿入されているように見えるため、行数に矛盾があります。

コントローラー デリゲートは非常にシンプルで標準的なものです。

-(void)controllerWillChangeContent:(NSFetchedResultsController*)controller {
   [self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
   // for testing purpose I am not doing any modification
   return;
}

-(void)controllerDidChangeContent:(NSFetchedResultsController*)controller {
   [self.tableView endUpdates];
}

誰がテーブルビューを更新しているのかまだわかりません

4

1 に答える 1

8

これは正常な動作だと思います。フェッチされた結果コントローラーは、変更を表示する前に保存する必要はありません。詳細ビューで行った変更を保存する前にマスターに表示したくない場合は、詳細ビュー用に別の NSManagedObject コンテキストを作成する必要があります。そうすれば、永続ストアに保存されたオブジェクトのみがフェッチされた結果コントローラーに戻されます。

于 2012-08-30T12:42:04.280 に答える