我正在通过Mac OS X(第4版)的Cocoa编程来工作,和许多其他人一样,我正面临挑战。具体来说,第8章,挑战1。由于无法独自解决问题,我从Life as Clay博客中找到了一些帮助。我在此处添加了解决方案,但出现以下错误:

2013-05-09 00:28:49.049 RaiseMan[58078:303] Error setting value for key path sortDescriptors of object <NSArrayController: 0x7fcee2a51900>[object class: RMPerson, number of selected objects: 1] (from bound object <NSTableView: 0x7fcee2a48750>): [<RMPerson 0x7fcee1c5c870> valueForUndefinedKey:]: this class is not key value coding-compliant for the key [personName valueForKeyPath:@"length"].

事实是,在尝试找出问题所在时,我已经在StackOverflow的所有位置上看到了此错误,而且我还没有发现它试图传达有关项目的哪些信息。我找不到解决方案之间的任何关联来理解此错误消息,因此无法使用它来弄清楚代码中发生了什么。

因此,长话短说,我并不是真正在寻求代码特有错误的帮助,而是更多地试图找出该错误消息的真正含义,以便我自己解决问题。但是,无论如何,这就是我想要做的。如果您不仅可以告诉我哪里出了问题,还可以告诉我为什么此错误适用于我在做什么,那将很棒。

在此特定实例中,我将TableView绑定(bind)到ArrayController。 ArrayController以employees(NSMutableArray)作为其模型键路径绑定(bind)到文件的所有者。 employeesRMPerson对象的数组,每个对象都有两个属性:personName(NSString)和expectedRaise(浮点数)。该表的第一列显示了各自personName中的RMPerson;我正在尝试根据挑战使用personName的长度对第一列进行排序。当我使用personName作为排序键并使用caseInsensitiveCompare:作为选择器对其进行排序时,一切都很好。当我使用[personName valueForKeyPath:@"length"]personName.length作为排序键并使用compare:作为选择器时,就会出现此错误。

最佳答案



没有。

完整的异常消息使问题更有意义:



这意味着至少就键值编码而言,该类的对象没有名为<key>的属性,因此您不能使用KVC从它们获取此类属性的值。

绑定(bind)是NSArrayController的重要组成部分,它使用KVC来获取和设置绑定(bind)属性以及已绑定(bind)它们的属性,因此,尝试将某些内容绑定(bind)到不存在的属性将获得此异常。

不过,您有一个特殊情况:



这意味着您尝试使用“[personName valueForKeyPath:@"length"]”作为密钥。

严格来说,KVC会接受几乎没有句点的任何内容作为键,但是实际上,很少有对象能够识别出不是标识符的任何键,并且所有这些对象(NSDictionary除外)都希望键能够至少是一个单词。 Objective-C消息表达式不是有效的密钥,并且不能成为密钥路径的一部分。

我猜想您实际上将“[personName valueForKeyPath:@"length"]”粘贴到了笔尖的“模型关键路径”字段中,以便从外观上将其用于数组 Controller 的sortDescriptors绑定(bind)。那行不通。 “模型关键路径”字段仅期望关键路径本身。
personName.length将是有效的键路径,但是假设您的RMPerson的名称是字符串,则不会为您提供排序描述符数组,因此可以期望数组 Controller 会阻塞数字数组。

无论您要做什么(按名称的长度排序?),都应该问另一个问题。



选择器并不重要。

请注意某些事物是期望键路径还是仅键-区别是微妙的,但应用程序非常重要。排序描述符需要一个键。

08-05 21:46