【问题标题】:How can I use NSFetchedResultsController to fetch results based on an entity's relationship?如何使用 NSFetchedResultsController 根据实体的关系获取结果?
【发布时间】: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;    

}

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

【问题讨论】:

    标签: iphone ios ipad core-data nsfetchedresultscontroller


    【解决方案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];
      

      你就完成了。 (抱歉,这完全不是您想要的)。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-20
        • 1970-01-01
        • 1970-01-01
        • 2012-09-24
        • 1970-01-01
        相关资源
        最近更新 更多