NSTreeController 基于瞬态 isRoot 异常获取谓词

Posted

技术标签:

【中文标题】NSTreeController 基于瞬态 isRoot 异常获取谓词【英文标题】:NSTreeController fetch predicate based on transient isRoot exceptions 【发布时间】:2010-08-31 04:04:42 【问题描述】:

我的基于文档的 Cocoa 应用程序使用 NSOutlineView/NSTreeController 组合,绑定到文档的核心数据存储。我的 NSTreeController 有获取谓词 isRoot == YESisRoot 是一个瞬态布尔属性,默认值为NO。我的根模型的awakeFromInsert 调用:

[self setIsRoot:[NSNumber numberWithBool:YES]];

我可以将对象添加到层次结构中,但是当我尝试加载我刚刚保存的文档时,我得到一个异常:

[<NSDictionaryMapNode 0x1001a8190> valueForUndefinedKey:]: this class is not key value coding-compliant for the key isRoot.

如果我在 xcdatamodel 中将isRoot 属性更改为非瞬态,我可以解决此异常并成功加载新保存的文档,但根据我对瞬态标志的理解,它不会导致问题,并且这确实不是应该持久化的数据。

我还尝试在 NSManagedObject 子类中实现 -isRoot 以返回适当的固定值,以及在 awakeFromFetch 中进行相同的 setIsRoot: 调用,均无济于事。

我还缺少其他一些微妙之处吗?我无法想象 fetch 谓词不支持瞬态属性。我不太了解 Core Data 的内部工作原理,但它试图在特定于商店的类而不是我的 NSManagedObject 子类上查找 isRoot 似乎很有趣。

【问题讨论】:

【参考方案1】:

我无法想象 fetch 谓词 不支持瞬态属性。

经过一番研究,我可以告诉你他们没有。 See this document.引用:

您无法使用谓词获取 基于瞬态特性 (虽然你可以使用瞬态 在内存中过滤的属性 自己)。

我已经编写了一个测试项目,并且可以验证我得到的错误与您完全相同。

当我需要过滤掉树中的根节点时,我使用parent == nil 的提取谓词而不是瞬态属性。

我理解你的反应——我也想拥有一个专门称为 isRoot 的属性。我的猜测是这是可能的,但它需要这么多代码,不值得这么麻烦。

哦,如果您处理的核心数据不止一点点,mogenerator 会让您的生活更轻松。

【讨论】:

John - 一个不幸的限制,但我认为这是有道理的,因为 fetch 谓词似乎在商店内运行。我也会检查 mogenerator。非常感谢您付出的额外努力! 顺便说一句,它确实让我想知道瞬变的价值是什么。也就是说,与手动添加到模型类的属性相比,它们有什么优势吗? 我没有足够的 Cocoa 经验来明确地告诉你,但我的猜测是该值是用于向用户显示计算值,而不是通过它们进行过滤。例如,您可能希望表格视图显示全名,但只有 firstName 和 lastName 字段。我没有时间深入研究这些可能性,但我相信它们还有其他用途。【参考方案2】:

另一种选择是为***节点设置一个单独的类,使用该类名称作为“实体名称”并将“获取谓词”留空。只要子节点与***节点具有相同的值(我使用通用的超类/实体继承),一切仍然有效。

【讨论】:

【参考方案3】:

您是否确定 NSTreeController 设置为控制实体而不是类?

根据您的错误,它看起来可能被设置为具有默认值的类 - NSMutableDictionary。

我还认为也许 isRoot 可以被持久化。当然,这取决于您尝试对您的应用执行什么操作,但如果它是在应用运行时加载的树视图,我会让 isRoot 持久化。

【讨论】:

John - 是的,我已将 NSTreeController 设置为实体模式,并填写了适当的类名。在这种特殊情况下,我相信 NSDictionaryMapNode 与 Core Data 如何将数据持久化到磁盘有关(我选择保存文档时的二进制文件,如果我选择 XML,则异常在 NSXMLDocumentMapNode 上)。

以上是关于NSTreeController 基于瞬态 isRoot 异常获取谓词的主要内容,如果未能解决你的问题,请参考以下文章

通过核心数据加载文件后,NSBrowser 不会从 NSTreeController 重新填充子项

基于瞬态属性获取的结果控制器 sectionIndexTitle

如何刷新基于_id(非瞬态)的关系与获取不同步的对象

从 CoreData 刷新 NSTreeController

将非模型节点添加到 NSTreeController

观察 NSTreeController 绑定的核心数据实体以进行插入/删除