2

我将我的iOS应用程序移植到Mac,并且想要设置一个NSTreeController来管理实体的层次结构。在这个层次结构中有两个不同的NSManagedObject类型,Group和Item,它们具有一对多的关系(一组到多个项目)。不过,我在设置NSTreeController时遇到了问题;我收到一条错误消息:NSTreeController与两个不同的核心数据NSManagedObject实体

[<NSManagedObject 0x10029c410> valueForUndefinedKey:]: the entity Item is not key value coding-compliant for the key "items". 

似乎NSTreeController旨在建立与一个类型NSManagedObject的,其子女是指本身,而且有孩子是不同种类的对象不起作用。它是否正确?如果是这样,我需要做些什么来纠正这一问题,同时保持新数据模型能够使用轻量迁移从旧数据模型正确迁移?如果我确实能够用两种不同类型的NSManagedObjects完成NSTreeObject,我应该如何设置它?

回答

2

在NSTreeController中使用的所有实体都必须响应setChildrenKeyPath:设置的指定子消息。在这种情况下,这将是items。换句话说,树形结构中的所有对象都必须对items消息做出响应,即使对象永远不会有任何子对象也不例外。假设你想建立一个文件系统并用NSTreeController显示它。你就必须有一个看起来像这样的数据模型:

FileSystemObject{ 
    name: 
    parent<<-->FileSystemObject.children 
    children<-->>FileSystemObject.parent 
} 

Folder:FileSystemObject{ 
} 

File::FileSystemObject{ 
} 

,那么你会覆盖提供FileSystemObject一个自定义的方法,将返回儿童的数量。您可以使用setCountKeyPath:将方法名称提供给NSTreeController。覆盖Folder中的方法以返回一个实际的子项数并在File中覆盖返回零。

这就是为什么NSTreeController没有很好的想法。与其他控制器不同,它通过强制您更改数据模型来满足UI的需求,从而打破封装,这是非常糟糕的做法。

有人写了一个替换树控制器,它只是自动假定任何不响应子对象的keypath对象都是一个叶子,并提供了一个自动子空间计数为零。不幸的是,我现在找不到它,不记得它叫什么了。