来自已查询实体的部分
Posted
技术标签:
【中文标题】来自已查询实体的部分【英文标题】:Sections from already queried Entity 【发布时间】:2011-09-04 21:37:01 【问题描述】:所以我在 UITableView 中显示一些实体。通过单击单元格,我想显示已经在“对多”关系中查询的其他实体。
例如,我正在显示一所学校的所有班级。现在我想显示一个班级的所有学生。这个学生已经可以作为NSSet
Class.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)
所以我认为它会查询所有延迟加载的学生,对吗?
【参考方案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 也会触发错误)。
所以你有两个选择:
-
在班级中管理了一个名为 studentsCount 的属性,该属性反映了学生中的实体数量。调用此属性不会触发关系错误。
使用 countForFetchRequest:
NSFetchRequest *req = [[NSFetchRequest alloc] init];
[req setEntity:[NSEntityDescription entityForName:@"Student" inManagedObjectContext:context]];
[req setPredicate:[NSPredicate predicateWithFormat:@"class = %@", myClass]];
第二个选项执行提取,但效率非常高,所以也许它足够有效 - 我没有进行性能测试,所以我不能说。
顺便说一句,如果您不确定关系是否触发了错误,您可以使用方法 hasFaultForRelationshipNamed。
【讨论】:
以上是关于来自已查询实体的部分的主要内容,如果未能解决你的问题,请参考以下文章