如何使用 NSFetchedResultsController 根据实体的关系获取结果?

发布于 2024-12-02 21:18:21 字数 1627 浏览 4 评论 0原文

我有 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;    

}

如果有人至少能指出我正确的方向,我将不胜感激......

I have 2 views that contain a UITableView each. They are both displayed at the same time, side by side, on an iPad.

I am using Core Data for all data. Both tables need to be edited (rows added, deleted, etc), so I'd like to use a NSFetchedResultsController in each view to handle all this for me.

The contents of the second table depend on what is selected in the first table. So, when selecting an item in the first table, that object is passed to the view with the second table (so I do already have access to the data that should go into the second table), but I'd like to try to use all the built-in handling of the NSFRC if possible.

The model is along the lines of: University (uniID, uniName, students) and Student (stuID, stuName, university). So the relationship is: University <-->> Student.

I'm using the following code in the NSFRC, but it's returning 0 results:

- (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;    

}

I would be most grateful if someone could at least point me in the right direction...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦里泪两行 2024-12-09 21:18:21

您还记得 performFetch: 吗?

IE

NSError *error;
BOOL success = [fetchedResultsController performFetch:&error];

Have you remembered to performFetch: ?

i.e.

NSError *error;
BOOL success = [fetchedResultsController performFetch:&error];
小嗲 2024-12-09 21:18:21

好的,所以我解决了这个问题。当然,当谓词项需要更改(即已选择大学)时,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];

我希望这对遇到类似情况的任何人有所帮助。

感谢阿什利提出的替代建议。

Ok, so I solved the issue. The NSFRC wasn't being updated when the predicate term needed to change (i.e. a University had been selected), of course, because of:

if (fetchedResultsController != nil) {
    return fetchedResultsController;
}

Having the NSFRC recreated every time it's called (by removing the above code) doesn't work either, because the fetch needs to be executed after it's been created, which can't happen just before numberOfRowsInSection is called (as this method calls, and therefore recreates, the NSFRC).

So, I added a BOOL to the view called newFetchRequired which is set to YES every time a new University is selected. In the NSFRC, the above code should be changed to:

if (fetchedResultsController != nil && !newFetchRequired) {
        return fetchedResultsController;
    }
newFetchRequired = NO;

The fetch is then performed correctly (which calls and recreates the NSFRC):

[self.fetchedResultsController performFetch:&error];

I hope this helps anyone in a similar situation.

Thanks to Ashley for the alternative suggestion.

陈甜 2024-12-09 21:18:21

我不知道你是否还在检查这个,我不太确定我是否正确理解你的问题..但是当你只想更改谓词时,为什么要从头开始创建 NSFRC 呢?我将这样做:

当选择一所新大学时,只需在此处添加代码即可:

NSFetchRequest *fetchRequest = [self.fetchedResultsController fetchRequest];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"university == %@",self.selectedUniversity];

[fetchRequest setPredicate:predicate];

NSError *error;
[fetchedResultsController performFetch:&error];

然后就完成了。 (很抱歉,如果这完全不是您想要的)。

编辑:您也可以简单地将其写入私有函数,并在每次选择大学时调用它。

I don't know if you're still checking this and I'm not quite sure if I understood your question correctly.. but why do you create the NSFRC from scratch when you just want to change the predicate? Here's how I would do it:

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];

and you're done. (Sorry if this is totally not what you were looking for).

edit: You could also simply write this into a private function and call it every time a university is selected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文