gpt4 book ai didi

core-data - NSSortDescriptor 按核心数据对多关系中的项目数进行排序

转载 作者:行者123 更新时间:2023-12-03 22:26:46 28 4
gpt4 key购买 nike

使用 Core Data 对多关系时,一个长期存在的问题是很难使用 NSSortDescriptor 对获取请求进行排序。在 Parent实体基于children的数量与 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
iOS 6.1 ,我通过添加 KVO 访问器发现了一个修复 -countOf<Key>作为我的托管对象模型的属性作为整数类型。我没有在我的 NSManagedObject 中为这个属性实现任何东西子类,因为所有的魔法似乎都发生在引擎盖下。 (见 https://stackoverflow.com/a/15546371/2042527)。

但是,这不适用于 iOS 6.0 .在这里我发现在你的 NSManagedObject中加入以下方法子类解决了这个问题:
- (NSUInteger)countOfChildren{
return [self.children count];
}

添加两者确实 不是 修复两个 SDK 中的问题。相反,它破坏了修复。

有没有人知道为什么会发生这种情况以及为什么两者之间存在差异,即使没有提到 iOS 6.0 和 iOS 6.1 之间对 Core Data 或 Foundation 的更改。

最佳答案

我认为通过说“Keypath 包含 KVC 聚合,其中不应该有一个;未能处理子项。@count” Core Data 想告诉你它不支持这种排序描述符。这很可能是因为当支持 SQLite 存储收到您的提取请求时,它必须生成执行提取请求描述的 SQL。 “children.@count”的情况实际上比人们想象的要复杂得多。

覆盖 -countOfChildren 的“修复”并不是真正的修复。让我们暂时假设这解决了问题,然后 -countOfChilden 将在每个 Parent 上调用。当您第一次访问 self.children 时,Core Data 需要执行一个 SQL 查询来确定(至少)子项的主键,创建 NSManagedObjectIDs、NSManagedObjects 并返回结果。如果这样做有效,那么您会看到非常糟糕的性能。

您的问题有多种解决方案。

1. 将子计数存储在持久属性

只需向您的父实体添加一个属性(名称:cachedCountOfChildren,类型:Integer 64 位)。在您的 Controller 层(不在您的模型层)中,每次将子项分配给父项时,将 cachedCountOfChildren 增加 1,每次从父项中删除子项时,将 cachedCountOfChildren 递减。然后在排序描述符键中使用 cachedCountOfChildren。这将有很好的表现。

2.使用字典结果

将您的 NSFetchRequest 的 resultType 设置为 NSDictionaryResultType。这将导致 -executeFetchRequest:error: 返回 NSDictionaries 而不是 NSManagedObjects。带有 NSDictionaryResultType 的 NSFetchRequest 可以做不同的事情。例如,您可以使用 setPropertiesToGroupBy 和 NSExpression (...)。请查看 WWDC session “Using iCloud with Core Data (2012)”(从幻灯片 122 开始)以供引用。基本上,它们向您展示了如何构造一个请求,该请求将返回一个包含具有以下结构的字典的数组:

(
{
countOfChildren = 1;
parentName = "hello";
},
{
countOfChildren = 134;
parentName = "dsdsd";
},
{
countOfChildren = 2;
parentName = "sdd";
}
)

如您所见,您将得到一个未排序的结果。但是通过 countOfChildren 对这个数组进行排序可以在内存中非常有效地完成。在这种情况下,Core Data 生成的 SQL 也将非常高效,您将能够准确指定字典应包含哪些属性。所以结果也应该是非常高效的内存。此解决方案的优点是您不必跟踪 countOfChildren。

您必须根据自己的情况决定哪种解决方案最适合自己。

关于core-data - NSSortDescriptor 按核心数据对多关系中的项目数进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15550861/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com