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

2024-02-10

使用 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(使用前将#替换为@)

NSSortDescriptor 按核心数据对多关系中的项目数量进行排序 的相关文章

随机推荐

  • 大表情符号在 Chrome 和移动浏览器上被截断

    我正在尝试在 HTML 或 CSS 中使用 unicode 显示一些大表情符号 然而 在Chrome中 一些表情符号的下半部分被切断 而另一些表情符号则显示得很好 它也无法在 Android 上的移动 Firefox 中呈现 工作表情符号示
  • 在 ng 构建期间修改 javascript 脚本标签的 src 位置

    我的 index html 文件在 ng 构建后包含以下文件 例如 如何使 Angular cli 在 src 文件夹位置添加 app src app vendor bundle js 我需
  • 自定义 Toast 取消不起作用

    我看到很多关于取消吐司的问题 他们都没有工作 我有一个定制的吐司 其代码除了一行之外都与http developer android com guide topics ui notifiers toasts html CustomToast
  • Android,如何取消闹钟? AlarmManager.cancel 不起作用

    我有一个应用程序 您可以在其中创建 5 个警报 其中要创建的警报显示在 ListView 中 并假设当 listView 的元素播放警报时 但应从列表视图中删除该项目 但警报会被删除以始终达到预定时间声音 我已经查看了很多有关如何删除警报的
  • 如何更改 GCC 的默认搜索目录 crti.o?

    我想指定 GCC 的搜索目录startfile and endfile crt1 o crti o and crtn o 通过 B在命令行上 GCC 驱动程序可以工作 但不方便 如何修改规格 文件 lib gcc x86 64 unknow
  • Sails v1.0:在 mongo 中使用自定义主键时出错

    我正在尝试 SailsJS v1 0 0 32 的测试版 但在配置自定义 ID 时遇到了一些问题 下面你会找到我当前的配置 The modelExample js module exports attributes id type stri
  • iOS 8.1 下 UIPopoverController 出现之前出现不可预测的延迟

    SDK 8 1 在 iOS 8 1 下运行时会出现此问题 但在 iOS 7 下运行时不会出现此问题 它仅适用于 iPad 该问题在模拟器和硬件设备上都会出现 下面的代码演示了一个视图控制器 其中包含一个具有 1 行的 UITableView
  • 未解析的外部符号 C++ 与汇编器

    我正在尝试在汇编器中创建函数以在 C 中使用它 我的问题是我无法编译我的代码 我正在使用 Visual studio 2012 我在构建定制中添加了 masm 所以我不知道出了什么问题 C include
  • Visual Studio 2019 错误 - 无法加载文件或程序集或其依赖项之一

    我在运行我的项目时遇到一些问题 当我尝试运行时 出现以下错误 FileNotFoundException 无法加载文件或程序集 Dapper Version 2 0 0 0 Culture neutral PublicKeyToken nu
  • 删除c中数组的重复名称

    这就是我要做的 c 应该可以删除具有指定名称的动物 如果存在更多同名动物 则应删除所有同名动物 这是我的代码 void deleteAnimalByName char animalName int nrOfAnimals ANIMAL an
  • 执行代码块一定次数

    所以我想执行一些代码N次 N 是文本框的值 例如 12 我不知道如何实现这一点 但我的脑海里浮现出这样的事情 For Each i as 1 in textbox1 text some code Next or dim num1 as in
  • asciidoc宏

    我使用 asciidoc 来渲染文本 我很难理解宏 我的目标是进行简单的宏处理 就像在 LaTeX 中一样 我想写两个宏 FOO应替换为 bar MYTEXT xyz 应替换为 This is my text xyz 也许用不同的方式传递参
  • 如何从 Android 版 Google+ API 获取当前位置?

    我需要从 Android 版 Google API 获取当前位置 我已经在 Google API 控制台中完成了所有操作 并将我的应用程序与带有 SHA1 和包名称的客户端 ID 链接起来 我成功获取了有关用户名 个人资料图片 封面图片 电
  • 如何在python3中使用ldap3绑定(验证)用户

    我正在尝试将一些代码更新为 python3 使用ldap3 http ldap3 readthedocs org en latest quicktour html版本 0 9 7 4 https pypi python org pypi l
  • 如何在android apk中保存私有字符串值?

    我知道我可以将字符串保存在 res values strings xml 中 但是如果有人反汇编 dex 文件或 apk 文件 那么他将能够看到硬编码字符串或 res values strings xml 字符串 有没有办法存储反汇编后不会
  • 有没有办法让 Eclipse 报告一般“catch (Exception e)”作为错误/警告(在 java 中)?

    我试图鼓励在 Java 代码中不捕获一般异常的最佳实践 例如 try catch Exception e bad 有没有办法在 Eclipse 中将其标记为错误 警告 我知道 PMD 会注意到这一点 但我现在宁愿避免将其集成到每个人的构建环
  • Android 按钮 KeyDown - KeyUp |不同的按钮事件

    我有一个关于开发 Android 应用程序的简单问题 问题是不同类型的按钮 例如 当我的手指放在按钮上时 音乐就会播放 但是当我的手指放在按钮上时 音乐就会停止 我怎样才能做到这一点 这可能是不同类型的按钮事件 但我不知道 我用谷歌搜索 但
  • 如何在简单的 Kivy 应用程序中将 Pandas 数据框显示为表格?

    我想构建一个简单的 Kivy 应用程序 要求用户输入一个整数 MTP 要求用户输入延迟间隔 delay 用户按下提交按钮后查询 url 然后从 该查询创建一个显示的 pandas 数据框 就像 表 在 Kivy 应用程序的主屏幕上 然后输出
  • 如何将标签中的文本与右侧对齐?

    这是我的文件标签 如果标签太长 它就会超出屏幕 从而使我不得不滚动 我已经尝试了以下属性 单独的时间 RightToLeft as Yes ContentAlignment作为右下或右上 然而 它们都不起作用 什么是正确的属性 尝试设置Au
  • NSSortDescriptor 按核心数据对多关系中的项目数量进行排序

    使用 Core Data 多关系时 这是一个长期存在的问题 很难使用以下命令对获取请求进行排序NSSortDescriptor on a Parent基于实体的数量children与 a 处于一对多关系Child实体 这在与NSFetche