所以我在UITableView中显示一些实体。单击一个Cell我想显示已经在“to-many”关系中查询的其他实体。
例如,我正在显示学校的所有课程。现在我想要显示所有班级的学生。此学生已在NSSet
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"];
使用这种方法,我会很好地将它们安排到各个部分。
但我已经让所有学生都参加了特定课程。有没有办法用初始化的NSFetchedResultsController
初始化NSSet
或做同样的事情?
当然,我可以手动安排我的NSSet,但不是有这么好的方式,就像它是一个新的查询?
提前谢谢。 如果不清楚,请发表评论。答案 0 :(得分:1)
我猜您只有两个选项:使用NSFetchedResultsController
或自行排序对象。
NSFetchedResultsController& NSPredicate:强>
优点:易于物品贬值;模型更改通知,例如在同步期间
缺点:不必要的重新提取
NSSet& NSSortDescriptor 强>
优点:没有回复
缺点:复杂的贬低;没有模型更改通知,例如在同步期间:您可能正在显示已被删除的学生
答案 1 :(得分:0)
你可以使用NSPredicate,它使用反向关系(从你的学生回到课堂)
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
...
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"class == %@", theClassThoseStudentsBelongTo];
[fetchRequest setPredicate:predicate];
NSFetchedResultsController *theFetchedResultsController = ...
答案 2 :(得分:0)
NSFetchedResultsController提取的对象的关系从故障开始,仅在需要时获取。这意味着如果我们不为第一个tableView使用“Student”实体,它将仅在我们需要时延迟加载。
然而,由于你需要知道学生的数量,情况稍微复杂一些,因为调用[class.students count]会触发错误。 (调用KVO @count也会触发故障)。
所以你有两个选择:
使用countForFetchRequest:
NSFetchRequest *req = [[NSFetchRequest alloc] init];
[req setEntity:[NSEntityDescription entityForName:@"Student" inManagedObjectContext:context]];
[req setPredicate:[NSPredicate predicateWithFormat:@"class = %@", myClass]];
第二个选项执行提取,但是非常有效,所以也许它足够有效 - 我没有进行性能测试,所以我真的不能说。
顺便说一句,如果您不确定该关系是否触发了错误,您可以使用方法hasFaultForRelationshipNamed。