У меня 2 просмотра. Одно отображение списков покупок из базовых данных с использованием NSFetchResultsController. Второй отображает элементы в этих списках, используя простые NSFetchRequests. Оба представления содержат UITableView.
При запуске приложения я создаю NSFetchResultsController (подкласс ActiveFetchResults)
-(id)initActiveFetch{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Lista" inManagedObjectContext:[CoreDataHandler context]];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"archive == 0 AND deleted == NO"];
[request setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"position" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
if (self=[[ActiveFetchResults alloc]
initWithFetchRequest:request
managedObjectContext:[CoreDataHandler context]
sectionNameKeyPath:nil
cacheName:nil])
{
self.delegate = self;
}
[request release];
return self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[self sections] count];
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (NSInteger)numberOfRowsInSection{
id <NSFetchedResultsSectionInfo> sectionInfo = [[self sections] objectAtIndex:0];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ActiveListsCell* cell;
cell = (ActiveListsCell*)[tableView dequeueReusableCellWithIdentifier:@"ActiveLists"];
if (cell == nil) {
cell = [[[ActiveListsCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"ActiveLists"] autorelease];
}
NSManagedObject *managedObject = [self objectAtIndexPath:indexPath];
[cell setLista: (Lista*)managedObject];
NSLog(@"%@, %@, %d ",managedObject, [managedObject name], [[managedObject items] count]);
cell.activeListsDelegate = self;
[cell.roundedView setAlpha:1.0];
cell.button.alpha = 1.0;
cell.counter.alpha = 1.0;
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self sections] objectAtIndex:section];
return [sectionInfo name];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [self sectionIndexTitles];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
return [self sectionForSectionIndexTitle:title atIndex:index];
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
//-(BOOL)performFetch:(NSError **)error{
// ActiveFetchResults* ss = self;
// self = [self initActiveFetch];
//
// self.listView = ss.listView;
// self.listView.activeFetch = self;
// [self.listView.tableView setDelegate:self];
// [self.listView.tableView setDataSource:self];
//
// [ss release];
// return [super performFetch:error];
//}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
if ([anObject isKindOfClass:[Lista class]]) {
Lista* lista = (Lista*)anObject;
if ([[lista deleted] boolValue]) {
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationLeft];
}
}
else
[self configureCell:[tableView cellForRowAtIndexPath:indexPath]
atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
-(void)configureCell:(UITableViewCell*)cell atIndexPath:(NSIndexPath*)indexPath{
ActiveListsCell* activeCell = (ActiveListsCell*)cell;
NSManagedObject *managedObject = [self objectAtIndexPath:indexPath];
[activeCell setLista: (Lista*)managedObject];
}
Когда я перехожу во второй режим просмотра и добавляю новый элемент для выбранного списка, добавляя объект элемента в данные ядра, а я возвращаюсь к списку, он все еще показывает старое количество объектов. И свойство items списка, которое должно отображать все объекты Items для этого списка, является объектом NSarray с количеством предметов, не включая новые добавленные объекты. Но во втором представлении отображаются все элементы с добавленными новыми.
В двух словах это выглядит как использование NSFetchResultsController. У меня все объекты заморожены с первой выборки и не реагируют на изменения, несмотря на использование функции "executeFetch:". При использовании простого NSFetchRequest во втором View все работает нормально.
Может кто-нибудь сказать мне, почему объекты NSFetchResultsController остаются замороженными и не изменяются при изменении записей основных данных?