使用 Core Data 多关系时,这是一个长期存在的问题,很难使用以下命令对获取请求进行排序NSSortDescriptor
on a Parent
基于实体的数量children
与 a 处于一对多关系Child
实体。这在与NSFetchedResultsController
。通常将排序描述符初始化为:
NSSortDescriptor *sortByNumberOfChildren = [[NSSortDescriptor alloc] initWithKey:@"children.@count" ascending:NO];
结果出现异常'Keypath containing KVC aggregate where there shouldn't be one; failed to handle children.@count
On iOS 6.1,我通过添加 KVO 访问器发现了修复方法-countOf<Key>
作为我的托管对象模型的整数类型的属性。我没有在我的中为这个属性实现任何东西NSManagedObject
子类,因为所有的魔法似乎都发生在幕后。 (看https://stackoverflow.com/a/15546371/2042527 https://stackoverflow.com/a/15546371/2042527).
但是,这不适用于iOS 6.0。在这里我发现将以下方法添加到您的NSManagedObject
子类解决了这个问题:
- (NSUInteger)countOfChildren{
return [self.children count];
}
添加两者确实not修复两个 SDK 中的问题。相反,它破坏了修复。
有谁知道为什么会发生这种情况以及为什么两者之间存在差异,尽管没有提到 iOS 6.0 和 iOS 6.1 之间对 Core Data 或 Foundation 的更改。
我认为,通过说“包含 KVC 聚合的密钥路径,其中不应该有一个;无法处理子项。@count”,Core Data 想要告诉您它不支持这种排序描述符。这很可能是因为当支持 SQLite 存储收到您的提取请求时,它必须生成执行提取请求所描述的操作的 SQL。 “children.@count”的情况实际上比人们想象的要复杂。
覆盖 -countOfChildren 的“修复”并不是真正的修复。让我们假设这解决了问题,然后 -countOfChilden 将在每个 Parent 上调用。当您第一次访问 self.children 时,Core Data 需要执行一个 SQL 查询来确定(至少)子级的主键,创建 NSManagedObjectIDs、NSManagedObjects 并返回结果。如果这有效,那么你会看到非常糟糕的性能。
您的问题有多种解决方案。
1. 将子计数存储在持久属性中
只需向您的父实体添加一个属性(名称:cachedCountOfChildren,类型:Integer 64 位)即可。在您的控制器层(不在您的模型层中),每次将子项分配给父项时,将 cachedCountOfChildren 加 1;每次从父项中删除子项时,将 cachedCountOfChildren 递减。然后,您在排序描述符键中使用cachedCountOfChildren。这将会有很棒的表现。
2. 使用字典结果
将 NSFetchRequest 的 resultType 设置为 NSDictionaryResultType。这将导致 -executeFetchRequest:error: 返回 NSDictionaries 而不是 NSManagedObjects。带有 NSDictionaryResultType 的 NSFetchRequest 可以做不同的事情。例如,您可以使用 setPropertiesToGroupBy 和 NSExpression (...)。请参阅 WWDC 会议“使用 iCloud 与 Core Data (2012)”(从幻灯片 122 开始)以供参考。基本上,它们向您展示了如何构造一个请求,该请求将返回一个包含具有以下结构的字典的数组:
(
{
countOfChildren = 1;
parentName = "hello";
},
{
countOfChildren = 134;
parentName = "dsdsd";
},
{
countOfChildren = 2;
parentName = "sdd";
}
)
正如您所看到的,您将得到一个未排序的结果。但是通过 countOfChildren 对这个数组进行排序可以在内存中非常有效地完成。在这种情况下,Core Data 生成的 SQL 也将非常高效,您将能够准确指定字典应包含哪些属性。所以结果也应该非常高效。此解决方案的优点是您不必跟踪 countOfChildren。
您必须根据您的情况决定哪种解决方案最适合您自己。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)