NSFetchResultsController объект обновления - PullRequest
0 голосов
/ 08 июня 2011

У меня 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 остаются замороженными и не изменяются при изменении записей основных данных?

1 Ответ

1 голос
/ 08 июня 2011

Возможные проблемы:

  1. Вы сохранили NSManagedObjectContext после обновления или добавления объектов?

  2. Попробуйте добавить этот случай

    case NSFetchedResultsChangeUpdate: [self.tableView reloadData]; break;

в вашем - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type методе

  1. попробуйте перезагружать данные просмотра таблицы каждый раз после выполнения выборки:

    [self.tableView reloadData];

  2. Если это все еще не работает, ознакомьтесь с примером кода рецептов основных данных Apple: http://developer.apple.com/library/ios/#samplecode/iPhoneCoreDataRecipes/Introduction/Intro.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...