Я реализую UITableViewController в сочетании с NSFetchedResultsController. Когда экземпляр UITableViewController создан, NSFetchedResultsController сконструирован (по существу, так же, как пример CoreDataBooks) с другим предикатом, основанным на выборе пользователя, сделанного на предыдущем контроллере.
Иногда я установил предикат следующим образом:NSFetchedResultsControllerDelegate методы не вызывается, если его предикат использует IN?
predicate = [NSPredicate predicateWithFormat:@"container = %@", aManagedObject];
иногда таким образом:
predicate = [NSPredicate predicateWithFormat:@"container IN (%@)", aNSMutableSetOfObjectsID];
Оба предиката работает нормально, потому что они выборки правильно все мои объекты, как и ожидалось. Проблема возникает, когда я пытаюсь вставить новый управляемый объект в список, когда установлен второй предикат. Infact в этом случае методы делегата FRC никогда не вызываются, поэтому tableview не обновляется автоматически.
Я уверен, что новый объект правильно добавлен в тот же контекст, который используется FRC, и что его отношение «контейнер» установлено так, что делегат должен быть запущен, но это не так!
То, что я пробовал:
Я говорю о том, что второй предикат работает нормально, потому что, если добавить новый объект, а затем вытолкнуть UITableViewController и нажмите на нее снова, заставляя все данные, которые будут refetched, новый объект появляется в списке без проблем.
Другого тест, который я сделал, чтобы заставить FRC быть пересчитан мгновенным после добавления нового объекта:
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
exit(-1);
}
[self.tableView reloadData];
нового объект отображается правильно.
Код:
- (NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController == nil) {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext *managedObjectContext = realEstate.managedObjectContext;
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Item" inManagedObjectContext:managedObjectContext]];
[fetchRequest setPredicate:[self getBasePredicate]];
NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name"
ascending:YES
selector:@selector(localizedCaseInsensitiveCompare:)];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:nameDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[nameDescriptor release];
[sortDescriptors release];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:@"sectionIndex"
cacheName:nil];
self.fetchedResultsController = aFetchedResultsController;
fetchedResultsController.delegate = self;
[aFetchedResultsController release];
[fetchRequest release];
}
return fetchedResultsController;
}
// return a predicate for the fetchedResultsController
- (NSPredicate *)getBasePredicate {
NSPredicate *predicate = nil;
if ([[managedObject valueForKey:@"subcontainersCount"] intValue] == 0)
// container without sons **(FIRST PREDICATE)**
predicate = [NSPredicate predicateWithFormat:@"container = %@", managedObject];
else {
// container with sons **(SECOND PREDICATE)**
predicate = [NSPredicate predicateWithFormat:@"container IN (%@)", [Container allDescendantsObjectID:(Container *)managedObject includeSource:YES]];
}
return predicate;
}
- (void)addNewItem {
Item *newItem = (Item *)[NSEntityDescription insertNewObjectForEntityForName:@"Item"
inManagedObjectContext:realEstate.managedObjectContext];
newItem.name = @"my new item";
newItem.container = aContainerManagedObject;
NSError *error = nil;
if (![realEstate.managedObjectContext save:&error]) {
abort();
}
}
Методы NSFetchedResultsControllerDelegate я использую, взяты из "More iPhone 3 развития". Полный код может быть указан here (стр. 30-31, 35).
Я могу разместить здесь, если необходимо.
Спасибо! У меня также была проблема, когда делегат FRC не вызывался, и хотя это была другая проблема, это оказалось проблемой для моего предиката. –