в моем приложении для iPhone я использую простую модель базовых данных с двумя сущностями ( Item и Property ):
Item
имя
свойства
свойство
имя
значение
элемент
Элемент имеет один атрибут (имя) и одно отношение «один ко многим» ( properties ).Его обратная зависимость вещь . Свойство имеет два атрибута в соответствии с обратной зависимостью.
Теперь я хочу показать мои данные в табличных представлениях на двух уровнях.Первый перечисляет все элементы;Когда выбрана одна строка, новый UITableViewController помещается в стек моего UINavigationController.Предполагается, что новый UITableView отображает все свойства (то есть их имена) выбранного элемента.
Для этого я использую NSFetchedResultsController
, хранящийся в переменной экземпляра.На первом уровне все работает нормально при настройке NSFetchedResultsController следующим образом:
-(NSFetchedResultsController *) fetchedResultsController {
if (fetchedResultsController) return fetchedResultsController;
// goal: tell the FRC to fetch all item objects.
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.moContext];
[fetch setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
[fetch setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetch setFetchBatchSize:10];
NSFetchedResultsController *frController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:self.moContext sectionNameKeyPath:nil cacheName:@"cache"];
self.fetchedResultsController = frController;
fetchedResultsController.delegate = self;
[sort release];
[frController release];
[fetch release];
return fetchedResultsController;
}
Однако на UITableView второго уровня я, кажется, что-то делаю не так.Я реализовал fetchedresultsController подобным образом:
-(NSFetchedResultsController *) fetchedResultsController {
if (fetchedResultsController) return fetchedResultsController;
// goal: tell the FRC to fetch all property objects that belong to the previously selected item
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
// fetch all Property entities.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Property" inManagedObjectContext:self.moContext];
[fetch setEntity:entity];
// limit to those entities that belong to the particular item
NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"item.name like '%@'",self.item.name]];
[fetch setPredicate:predicate];
// sort it. Boring.
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
[fetch setSortDescriptors:[NSArray arrayWithObject:sort]];
NSError *error = nil;
NSLog(@"%d entities found.",[self.moContext countForFetchRequest:fetch error:&error]);
// logs "3 entities found."; I added those properties before. See below for my saving "problem".
if (error) NSLog("%@",error);
// no error, thus nothing logged.
[fetch setFetchBatchSize:20];
NSFetchedResultsController *frController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:self.moContext sectionNameKeyPath:nil cacheName:@"cache"];
self.fetchedResultsController = frController;
fetchedResultsController.delegate = self;
[sort release];
[frController release];
[fetch release];
return fetchedResultsController;
}
Теперь это становится странным.Приведенный выше оператор NSLog
возвращает мне правильное количество свойств для выбранного элемента.Тем не менее, метод UITableViewDelegate говорит мне, что нет никаких свойств:
-(NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
NSLog(@"Found %d properties for item \"%@\". Should have found %d.",[sectionInfo numberOfObjects], self.item.name, [self.item.properties count]);
// logs "Found 0 properties for item "item". Should have found 3."
return [sectionInfo numberOfObjects];
}
Та же самая реализация прекрасно работает на первом уровне.
Становится еще страннее.Я реализовал какой-то интерфейс для добавления свойств.Я создаю новый экземпляр Property через Property *p = [NSEntityDescription insertNewObjectForEntityForName:@"Property" inManagedObjectContext:self.moContext];
, устанавливаю отношения и вызываю [self.moContext save:&error]
.Кажется, это работает, поскольку error
по-прежнему nil
и объект сохраняется (я вижу количество свойств при регистрации экземпляра Item , см. Выше).Однако методы делегата не запускаются.Это кажется мне из-за возможно испорченного fetchRequest (Controller).
Есть идеи?Я испортил второй запрос на получение?Является ли это правильным способом извлечения всех сущностей в отношении «многие ко» для конкретного экземпляра?