如何使用 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。 (实体:学生;谓词:(大学 == nil);sortDescriptors:((“(stuName,升序,比较:)”));批量大小:20;类型:NSManagedObjectResultType;)。创建 NSFRC 时,大学是零。我怎样才能更新它以使用所选的大学? 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

为啥不能两次获取相同的数据? NSFetchedResultsController 为空

[精选] Mysql分表与分库如何拆分,如何设计,如何使用

如果加入条件,我该如何解决。如果使用字符串连接,我如何使用

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]