私はこの問題のトラブルシューティングを数時間行っていますが、今のところ成功していません。私はここで私の問題に関連しているかもしれないSOに関するすべての質問を読みました。
次のような1対多の関係を介してツリーのような構造で相互に接続されている2つのエンティティ(A、B)があります:A<--->>B。
NSFetchedResultsControllerに裏打ちされたUITableViewControllerがあり、エンティティAの選択されたオブジェクトに関連するエンティティBのすべてのオブジェクトを表示します。そのための述語を使用しています。
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"B" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"controlDate" ascending:NO];
NSArray *sortDescriptors = @[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSMutableArray *subpredicates = [NSMutableArray array];
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"isRelatedTo = %@", selectedObjectOfA];
[subpredicates addObject:predicate1];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"syncStatus != %d", ObjectDeleted];
[subpredicates addObject:predicate2];
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];
[fetchRequest setPredicate:predicate];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _fetchedResultsController;
}
オブジェクトの追加、削除、編集はすべて正常に機能します。テーブルはそれに応じて更新されます。私のクラスはNSFetchedResultsControllerDelegateに準拠しており、デリゲートメソッドは定型文です。
ただし、ユーザーがナビゲーションスタックに戻らずに[上へ] / [下へ]ボタンをタップすることで、エンティティAのすべてのオブジェクトを循環できるようにしたいと考えています(メールアプリで直接メールを循環できるように)。BのrelatedObjectの数は、選択したAのObjectによって異なります(noneと20の間)。
そして、ここで問題が発生します。私の意図は、述語を変更してFRCの結果を更新することです(構造や構文ではなく、「selectedObjectOfA」の値のみを呼び出して呼び出します)。
[self.fetchedResultsController performFetch:&error];
残りはすべてFRCが行う必要があります。
最初の質問は次のとおりです。このアプローチは正しいですか?
これが私がすでに試したシナリオです:
'selectedObjectOfA'を新しい値に設定し、performFetchを呼び出すだけで、常に同じ結果が表示されます(fetchRequestと述語が更新されていないため)
このようにFRCのfetchrequestを「リセット」します
NSMutableArray *subprediactes = [NSMutableArray array]; NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"isRelatedTo = %@", self.selectedObjectOfA]; [subprediactes addObject:predicate1]; NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"syncStatus != %d", ObjectDeleted]; [subprediactes addObject:predicate2]; NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subprediactes]; [self.fetchedResultsController.fetchRequest setPredicate:predicate];
FRCを更新し、私が推測するように正しいデータを返しますが、アプリが誤った行数でクラッシュします
'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 (5), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
NSFetchedResultsControllerデリゲートメソッドが呼び出されないためです。したがって、tableViewの行数は新しい結果に適合しません(返されたオブジェクトの数はエラーメッセージに従って正しいです)。
2番目の質問は、オブジェクトを追加/削除するときにデリゲートが起動するのに、述語(したがって結果)が変更された後ではないのはなぜですか?
前もって感謝します。