Извините за мой страшный английский. У меня большая проблема в моем приложении iOS. Приложение имеет большую базу данных, которая управляется Core Data. И у меня есть много контроллеров TableView для отображения этих данных. Любые изменения в базе данных должны отображаться в виде таблицы. Это может быть достигнуто путем реализации протокола делегатов NSFetchedResultsController. Вся реализация очень проста, как в книгах. Если приложение запускается в первый раз на тренажере и добавить новые записи в некоторых таблицах рядом делегат метода успешно обжигала:NSFetchedResultsController делегат запускает методы только при первом запуске приложения
– controllerWillChangeContent:
– controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
– controllerDidChangeContent:
После остановки отладки и запустить приложение снова ни один из перечисленных методов не увольняют. Они звонят только после того, как будет выполнена операция [managedObjectContext save]
.
У вас есть идеи, почему это происходит?
Исходный код:
//IssueProfileViewController.h class implements NSFetchedResultController delegate methods
- (NSFetchedResultsController*)fetchedResultsController{
if (_fetchedResultsController == nil) {
NSManagedObjectContext *managedObjectContext = self.issue.managedObjectContext;
NSFetchRequest *aFetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"IssueHistoryItem" inManagedObjectContext:managedObjectContext];
[aFetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"created" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
//NSPredicate *predicate = [[NSPredicate predicateWithFormat:@"issue == %@ && isComment == NO", self.issue] retain];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"issue == %@ && isComment == NO", self.issue];
[aFetchRequest setSortDescriptors:sortDescriptors];
[aFetchRequest setPredicate:predicate];
NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:aFetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
[aFetchRequest release];
//[predicate release];
[sortDescriptors release];
[sortDescriptor release];
_fetchedResultsController = aFetchedResultsController;
_fetchedResultsController.delegate = self;
}
return _fetchedResultsController;
}
-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
-(void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
NSArray *paths;
// NSIndexSet *section = [NSIndexSet indexSetWithIndex:[newIndexPath section]];
NSIndexPath *cellContentIndexPath;
switch (type) {
case NSFetchedResultsChangeInsert:
// paths = [NSArray arrayWithObject:newIndexPath];
if (![anObject isKindOfClass:[ChangeIssueDimensionValueHistoryItem class]]) {
cellContentIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row inSection:newIndexPath.section];
paths = [NSArray arrayWithObject:cellContentIndexPath];
[self.tableView insertRowsAtIndexPaths:paths
withRowAnimation:UITableViewRowAnimationFade];
[self sendMessageAboutObjectsCountChanged];
}
break;
case NSFetchedResultsChangeDelete:
paths = [NSArray arrayWithObject:indexPath];
[self.tableView deleteRowsAtIndexPaths:paths
withRowAnimation:UITableViewRowAnimationFade];
[self sendMessageAboutObjectsCountChanged];
break;
case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[self.tableView cellForRowAtIndexPath:indexPath]
withIssueHistoryItem:[self.fetchedResultsController objectAtIndexPath:indexPath]];
break;
default:
break;
}
}
Благодарим вас за ответ! Но если я правильно понимаю, когда я добавляю новый объект в контекст, ему приходится запускать 'processPendingChanges'? Или нет? – hex
Да, tableView должен обновиться, если NSSMetchedResultsController NSManagedObjectContext получит processPendingChanges. И (повторяя здесь) это происходит автоматически, когда контекст сохраняется. – JacobFennell