我想获取与对象A具有多对多关系的对象B(即A - >>> B)。我已经记忆中有A.我知道我可以从A中获取B对象的NSSet,但最好是对B对象进行获取请求(特别是如果我想在UITableView中按日期排序)?
我如何提出仅获取属于单个对象A的B对象的请求?
答案 0 :(得分:6)
如果您已经持有A的实例,只需通过A的访问者访问相关的B实例。
如果你需要直接获取与特定A相关的所有B(在这种情况下你不是),你将为B实体构建一个获取请求,其中一个谓词基于(反向)关系Bs到A.(具体语法取决于反向关系名称,以及该反转是一对一还是多对。)
答案 1 :(得分:5)
您必须在B组中指定反向关系才能完成您的要求。
但是,我不确定你为什么要反对(没有双关语)来抓取对象A中已有的B对象集。即使对象本身是延迟加载的,因为你已经在内存中有A,我有预感(虽然专家需要验证),从A中获取集合比指定新的NSPredicate更有效,并创建一个全新的Fetch。
当然,通过“更高效”我们谈论毫秒,即使在像iPhone一样慢的设备上也是如此。我从对象A抓取集合,因为语法更清晰。它也可能更快的事实是奖金。
答案 2 :(得分:5)
你需要在你的A的objectID中使用谓词,如下所示:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *BEntity = [NSEntityDescription entityForName:@"B" inManagedObjectContext:moc];
[fetchRequest setEntity:BEntity];
NSPredicate *predicate = [NSPredicate
predicateWithFormat:@"(relationship_to_a = %@)", [yourAInstance objectID]];
[fetchRequest setPredicate:predicate];
其中relationship_to_a是B管理对象中与A的关系的名称。
希望这有帮助。
顺便说一句:对于那些建议使用关系集中的错误的其他答案:我自己尝试了这个,并且它比取得它们慢得多,因为Core Data显然一个接一个地触发故障(不是批量),因此对于较大的套装来说会很慢。
实际上,如果通过提取获得A实例,则可以尝试将NSFetchRequest中的 relationshipKeyPathsForPrefetching 设置为YES,然后关系中的所有对象都不应该是错误。但这对我没有用,所以我坚持使用'获取解决方案'。
答案 3 :(得分:2)
我处于类似情况。
我想使用NSFetchedResultsController管理一对多(A - >> B)关系中的B。现在,一种方法是构建一个类似下面的谓词并将其应用于实体B:
NSPredicate *Predicate = [NSPredicate predicateWithFormat:
@"ANY hasParent.label == 'A'"];
但这是一种非常缓慢的做事方式,应该不惜一切代价避免。 我在25,000个对象上尝试了这个以检索大约300个,并且模拟器花费了大约15秒。它无法完成iPhone上的抓取并反复崩溃。
另一种方法是做已经提到的事情,从A持有的集合中创建一个NSArray并对其进行排序。如果将allObjects发送到一个集合,则会返回一个数组。 A是之前获取的NSManagedObject。
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:@"Name"
ascending:YES];
NSArray *lotsOfB = [[[A hasRelationsTo]
allObjects]
sortedArrayUsingDescriptors: sortDescriptors];
这非常快。在模拟器或设备上没有滞后。但你不能使用NSFetchedResultsController悲伤的时间: - (
希望有所帮助。
答案 4 :(得分:0)
我也处于类似情况。
我没有像pingbat那样多的对象,但用“ANY hasParent.label =='A'”获取它需要15秒。
我确实需要使用NSFetchedREsultsController,因此我必须重新构建模型。我所做的是将to-many关系存储为字符串属性并构造谓词“hasParent contains%@”。
我学到的教训是,有一个横向对多关系的谓词会有很大的性能影响。