Cocoa 基于瞬时isRoot异常的NSTreeController获取谓词

Cocoa 基于瞬时isRoot异常的NSTreeController获取谓词,cocoa,core-data,nstreecontroller,Cocoa,Core Data,Nstreecontroller,我的基于文档的Cocoa应用程序使用绑定到文档核心数据存储的NSOutlineView/NSTreeController组合。我的NSTreeController具有fetch谓词isRoot==YESisRoot是一个临时布尔属性,默认值为NO。我的根模型的awakeFromInsert调用: [self setIsRoot:[NSNumber numberWithBool:YES]] 我可以将对象添加到层次结构中,但当我尝试加载刚保存的文档时,会出现异常: [valueForUndefine

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

[self setIsRoot:[NSNumber numberWithBool:YES]]

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

[valueForUndefinedKey:]:该类不符合密钥isRoot的键值编码要求。

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

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


我还缺少其他微妙之处吗?我无法想象fetch谓词不支持瞬时属性。我对核心数据的内部工作原理了解不多,但它试图在特定于存储的类而不是我的NSManagedObject子类上查找
isRoot
,这似乎很有趣。

您是否确保将NSTreeController设置为控制实体而不是类

从您的错误来看,它可能被设置为具有默认-NSMutableDictionary的类

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

我无法想象这个获取谓词 不支持瞬态属性

经过一点研究,我可以告诉你他们没有。引述:

不能使用谓词获取 基于瞬态特性 (尽管您可以使用transient 要在内存中筛选的属性 你自己)

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

当我需要过滤掉树中的根节点时,我使用
parent==nil
的fetch谓词,而不是transient属性

我理解你们的反应——我也希望有一种特别称为isRoot的属性。我猜这是可能的,但是需要太多的代码,不值得这么麻烦


哦,如果您处理核心数据的时间稍长,将使您的生活更加轻松。

另一种选择是为顶级节点使用单独的类,将该类名用作“实体名”,并将“获取谓词”留空。只要子节点的值与顶级节点的值相同(我使用一个通用的超类/实体继承),一切都可以正常工作。

John-是的,我已将NSTreeController设置为实体模式,并填写了相应的类名。在这种情况下,我认为NSDictionaryMapNode与核心数据如何将数据持久化到磁盘有关(保存文档时,我选择了二进制,如果选择XML,则NSXMLDocumentMapNode上会出现异常)。John-这是一个不幸的限制,但我认为它有一定的意义,因为fetch谓词似乎在存储中运行。我也会查一下莫盖纳。非常感谢你多跑了一英里!顺便说一句,它确实让我想知道瞬变的价值是什么。也就是说,与手动添加到模型类中的属性相比,它们有什么优势吗?我没有足够的Cocoa经验来确切地告诉您,但我猜它们的值是用于向用户显示计算值,而不是按它们进行过滤。例如,您可能希望表视图显示全名,但只有firstName和lastName字段。我还没有时间深入研究这些可能性,但我相信它们还有其他用途。