在我的iPhone应用程序中我使用简单的核心数据模型和两个实体(项和属性):
物品
命名
属性
属性
命名
值
项目
项目有一个属性(名称)和一对多关系(属性)。它的反比关系是 item 。 属性有两个属性,即反向关系。
现在我想在两个级别的表视图中显示我的数据。第一个列出所有项目;当选择一行时,新的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];
}
同样的实现在第一级工作正常。
它变得更加怪异。我实现了某种UI来添加属性。我通过Property *p = [NSEntityDescription insertNewObjectForEntityForName:@"Property" inManagedObjectContext:self.moContext];
创建了一个新的 Property 实例,设置关系并调用[self.moContext save:&error]
。这似乎有效,因为error
仍然是nil
并且对象被保存(我可以在记录 Item 实例时查看属性数量,请参见上文)。但是,不会触发委托方法。这似乎是由于可能搞砸了fetchRequest(Controller)。
有什么想法吗?我弄乱了第二次获取请求吗?这是否是为特定实例获取多对多关系中的所有实体的正确方法?
答案 0 :(得分:2)
您需要实际执行表视图控制器的提取:
// ...create the fetch results controller...
NSError *fetchRequestError;
BOOL success = [fetchedResultsController performFetch:&fetchRequestError];