如何使用 NSFetchedResultsController 根据实体的关系获取结果?
Posted
技术标签:
【中文标题】如何使用 NSFetchedResultsController 根据实体的关系获取结果?【英文标题】:How can I use NSFetchedResultsController to fetch results based on an entity's relationship? 【发布时间】:2011-09-05 11:50:11 【问题描述】:我有 2 个视图,每个视图都包含一个 UITableView。它们在 iPad 上同时并排显示。
我对所有数据都使用 Core Data。两个表都需要编辑(添加、删除行等),所以我想在每个视图中使用 NSFetchedResultsController 来为我处理所有这些。
第二个表的内容取决于第一个表中选择的内容。因此,当在第一个表中选择一个项目时,该对象将被传递给第二个表的视图(所以我已经可以访问应该进入第二个表的数据),但我想尝试使用如果可能,NSFRC 的所有内置处理。
该模型类似于:大学(uniID、uniName、学生)和学生(stuID、stuName、大学)。所以关系是:大学>学生。
我在 NSFRC 中使用以下代码,但它返回 0 个结果:
- (NSFetchedResultsController *)fetchedResultsController
if (fetchedResultsController != nil)
return fetchedResultsController;
NSManagedObjectContext *context = appDelegate.managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]initWithKey:@"stuName" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:20];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"university == %@",self.selectedUniversity];
[fetchRequest setPredicate:predicate];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
fetchedResultsController.delegate = self;
[sort release];
[fetchRequest release];
[theFetchedResultsController release];
return fetchedResultsController;
如果有人至少能指出我正确的方向,我将不胜感激......
【问题讨论】:
【参考方案1】:你还记得performFetch:
吗?
即
NSError *error;
BOOL success = [fetchedResultsController performFetch:&error];
【讨论】:
谢谢阿什利。是的,我正在执行提取,但 numberOfRowsInSection 中返回的行数为 0。 可以记录 fetchRequest 以确认它包含您所期望的内容(并在此处发布?) 获取请求显示搜索词为nil。selected
属性添加到您的大学实体,该属性在第一个tableView 中选择大学时设置,然后将您的谓词更改为[NSPredicate predicateWithFormat:@"university.selected == %@", [NSNumber numberWithBool: YES]];
谢谢阿什利。看起来这会起作用,但我想知道是否有更简洁的方法可以做到这一点,因为我要么必须取消选择以前选择的大学,然后选择新的大学,要么遍历所有大学以先取消选择它们。有趣的是,我只是尝试在每次调用 NSFRC 时重新创建它(所以谓词不是 nil),并在 University 模型中添加一个 universityID 供 NSFRC 搜索(而不是 University 对象本身)。它仍然带回 0 行。我认为可能有比最初想象的更严重的错误......【参考方案2】:
好的,所以我解决了这个问题。当谓词需要更改(即选择了大学)时,NSFRC 没有更新,当然,因为:
if (fetchedResultsController != nil)
return fetchedResultsController;
每次调用 NSFRC 时都重新创建它(通过删除上面的代码)也不起作用,因为在创建它之后需要执行提取,这不能在调用 numberOfRowsInSection 之前发生(因为这个方法调用并因此重新创建 NSFRC)。
所以,我在名为 newFetchRequired 的视图中添加了一个 BOOL,每次选择一所新大学时它都设置为 YES。在NSFRC中,上面的代码应该改成:
if (fetchedResultsController != nil && !newFetchRequired)
return fetchedResultsController;
newFetchRequired = NO;
然后正确执行提取(调用并重新创建 NSFRC):
[self.fetchedResultsController performFetch:&error];
我希望这对处于类似情况的任何人有所帮助。
感谢 Ashley 的替代建议。
【讨论】:
【参考方案3】:我不知道你是否还在检查这个,我不太确定我是否正确理解了你的问题。但是当你只想更改谓词时,为什么要从头开始创建 NSFRC?以下是我的做法:
When a new University is selected just add in the code right there:
NSFetchRequest *fetchRequest = [self.fetchedResultsController fetchRequest];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"university == %@",self.selectedUniversity];
[fetchRequest setPredicate:predicate];
NSError *error;
[fetchedResultsController performFetch:&error];
你就完成了。 (抱歉,这完全不是您想要的)。
编辑:您也可以简单地将其写入私有函数并在每次选择大学时调用它。
【讨论】:
以上是关于如何使用 NSFetchedResultsController 根据实体的关系获取结果?的主要内容,如果未能解决你的问题,请参考以下文章
启动 Core Data 应用程序时在后台配置 NSFetchedResultsController