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

时间:2011-09-05 11:50:11

标签: iphone ios ipad core-data nsfetchedresultscontroller

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

}

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

3 个答案:

答案 0 :(得分:0)

你记得performFetch:吗?

即。

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

答案 1 :(得分:0)

好的,所以我解决了这个问题。当谓词术语需要改变时(即大学被选中),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的替代建议。

答案 2 :(得分:0)

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

选择新大学后,只需在代码中添加:

NSFetchRequest *fetchRequest = [self.fetchedResultsController fetchRequest];

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

[fetchRequest setPredicate:predicate];

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

你已经完成了。 (对不起,如果这完全不是你想要的那样)。

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