【问题标题】:Sections from already queried Entity来自已查询实体的部分
【发布时间】:2011-09-04 21:37:01
【问题描述】:

所以我在 UITableView 中显示一些实体。通过单击单元格,我想显示已经在“对多”关系中查询的其他实体。

例如,我正在显示一所学校的所有班级。现在我想显示一个班级的所有学生。这个学生已经可以作为NSSetClass.students下的Class.students使用

现在我想在不同的部分显示学生的第一个字母。

如果我想直接从 CoreData 获取它们,我会做类似的事情

// init fetch request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:self.managedObjectContext];

// Search only specific students
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"class == %@", theClassThoseStudentsBelongTo];
[fetchRequest setPredicate:predicate];

// Generate it
NSFetchedResultsController *theFetchedResultsController = 
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                        managedObjectContext:self.managedObjectContext 
                                          sectionNameKeyPath:@"firstLetter" 
                                                   cacheName:@"StudentTable"];

使用这种方法,我可以将它们很好地排列成部分。

但我已经拥有特定班级的所有学生。有没有办法用初始化的NSSet 初始化NSFetchedResultsController 或做一些相同的事情?

当然,我可以手动安排我的 NSSet,但没有像新查询那样的好方法吗?

提前致谢。 如果有不清楚的地方,请发表评论。

【问题讨论】:

  • 对答案感到好奇,因为我很久以前就遇到过同样的问题,并采取了手动实现所有事情的艰难道路(不难但不方便且不优雅)。
  • 您是希望在单个 tableview 中完成所有这些工作,还是使用 Class-->>class.students 设置分层 tableview?
  • 我有一个带有“classes”的tableview,然后在点击一个类后,一个带有“students”的tableview。
  • 在第一个tableView中使用“学生”吗? (有类的那个?)因为如果我没记错的话,NSFetchedResultsController 获取的对象一开始是错误的,所以学生关系只有在需要时才会延迟加载。
  • 我以某种方式使用它们。我只想知道是否至少存在一名学生。所以我做if (aClass.students) {} 所以我认为它会查询所有延迟加载的学生,对吗?

标签: iphone objective-c ios core-data uitableview


【解决方案1】:

我猜你只有两个选择:使用NSFetchedResultsController 或自行排序对象。

NSFetchedResultsController 和 NSPredicate:
优点:容易删除对象;模型更改通知,例如同步期间
缺点:不必要的重新获取

NSSet 和 NSSortDescriptor
优点:无需重新获取 缺点:删除复杂;没有模型更改通知,例如在同步期间:您可能正在显示已被删除的学生

【讨论】:

    【解决方案2】:

    您可以使用使用反向关系的 NSPredicate(从您的学生回到班级)

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    ...
    
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"class == %@", theClassThoseStudentsBelongTo];
    [fetchRequest setPredicate:predicate];
    
    NSFetchedResultsController *theFetchedResultsController = ...
    

    【讨论】:

    • 但这不是再次从sqlite数据库查询学生吗?
    • 很可能是这样。您可以选择使用更多查询的 NSFetchedResultsController 或手动按部分排列对象。
    【解决方案3】:

    NSFetchedResultsController 获取的对象的关系一开始是错误的,并且仅在需要时才获取。这意味着如果我们不为第一个 tableView 使用“Student”实体,它将仅在我们需要时才延迟加载。

    但是,由于您需要知道学生人数,因此情况有点复杂,因为调用 [class.students count] 会触发错误。 (调用 KVO @count 也会触发错误)。

    所以你有两个选择:

    1. 在班级中管理了一个名为 studentsCount 的属性,该属性反映了学生中的实体数量。调用此属性不会触发关系错误。
    2. 使用 countForFetchRequest:

      NSFetchRequest *req = [[NSFetchRequest alloc] init];
      [req setEntity:[NSEntityDescription entityForName:@"Student" inManagedObjectContext:context]];
      [req setPredicate:[NSPredicate predicateWithFormat:@"class = %@", myClass]];
      

    第二个选项执行提取,但效率非常高,所以也许它足够有效 - 我没有进行性能测试,所以我不能说。

    顺便说一句,如果您不确定关系是否触发了错误,您可以使用方法 hasFaultForRelationshipNamed。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-13
      • 1970-01-01
      • 2015-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-01
      相关资源
      最近更新 更多