我是时候在我的程序中实现键值编码,所以我对它不太满意。我有控制器类,其中解析方法在启动文档中实现我已初始化对象和键。 Universal类的所有数据成员都是type id。
univ=[[Universal alloc] init];
[univ setValue:univ.datamember1 forKey:@"1"];
[univ setValue:univ.datamember2 forKey:@"2"];
[univ setValue:univ.datamember3 forKey:@"3"];
[univ setValue:univ.datamember4 forKey:@"4"];
[univ setValue:univ.datamember5 forKey:@"5"];
我在end element方法中设置数据成员的值:
id temp1=[univ valueForKey:@"1"];
temp1=strVal;
[resultArray addObject:univ];
我为此代码获得以下异常:
'NSUnknownKeyException', reason: '[<Universal 0x6e994d0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key 1
这是什么原因。是否遗漏了某些东西或一切都出错了?
答案 0 :(得分:2)
在大多数情况下,您不必实施键值编码。相反,您创建的类符合各种约定,然后键值编码自动为它工作。
这些约定是关于如何命名方法以便通过KVC访问属性。
您的代码:
univ=[[Universal alloc] init];
[univ setValue:univ.datamember1 forKey:@"1"];
[univ setValue:univ.datamember2 forKey:@"2"];
[univ setValue:univ.datamember3 forKey:@"3"];
[univ setValue:univ.datamember4 forKey:@"4"];
[univ setValue:univ.datamember5 forKey:@"5"];
很奇怪。你想在这做什么?此代码看起来,就像它试图从univ
对象的其他属性设置univ
对象的属性一样。这将是多余的。
我怀疑你认为你在这里建立同义词或别名 - 你正在为属性datamember1
制作关键的“1”地图。那不对。 -setValue:forKey:
方法用于实际设置属性的值。这非常像调用setter方法;实际上,它通常会导致调用setter方法。
所以,你写的内容非常类似于:
univ=[[Universal alloc] init];
[univ set1:univ.datamember1];
[univ set2:univ.datamember2];
[univ set3:univ.datamember3];
[univ set4:univ.datamember4];
[univ set5:univ.datamember5];
我怀疑那是你打算做的事情。它可以帮助您解释您在非KVC术语中尝试做什么。您尝试更改哪些属性(如果有)?你想给他们什么价值?你会如何使用普通的制定者和吸气剂来做到这一点?
稍后,您发布了此代码:
id temp1=[univ valueForKey:@"1"];
temp1=strVal;
[resultArray addObject:univ];
同样,这很奇怪而且令人困惑。我怀疑你正在尝试更改univ
上的属性值,但这不是代码完成的内容,即使它可以工作。第一行尝试获取univ
对象的属性值,其中属性的名称为“1”。这不是房产的有效名称。无论如何,它将检索到的值存储到局部变量temp1
中。第二行简单地抛弃第一行的结果,并将不同的值存储到本地temp1
变量中。 temp1
变量独立于univ
对象,即使它刚刚存储从univ
对象检索的结果。更改temp1
无法更改univ
(尽管temp1
指向的对象的消息传递可能会更改该对象,univ
也可能指向该对象。
在我看来,您尚未准备好使用键值编码。您需要更好地了解基础知识。此外,几乎不需要使用带有静态编译时密钥的键值编码。键值编码用于在编译时不知道该属性的名称时动态访问对象的属性,但在运行时将使用名称作为数据。
答案 1 :(得分:0)
请阅读Apple ensuring KVC compliance上的文档中的部分。
它说:
对于属性或一对一关系的属性,这需要您的类:
- 实施名为 - &lt; key&gt;, - is&lt; Key&gt;的方法,或者具有实例变量&lt; key&gt;或_&lt; key&gt;。
- 如果属性是可变的,那么它也应该实现-set&lt; Key&gt;:。
合成属性也有资格实现方法,因此您的Universal
类需要一个名为1
(和2
等)的方法和另一个名为set1:
的方法当然没有,因为方法名称以数字开头是非法的。
答案 2 :(得分:0)
您尚未为要尝试访问的密钥实施setter和getter,并且尚未实现-setValue:forUndefinedKey:
。
在运行时,NSObject的-setValue:forKey:
实现查找名为“set1:”的方法,如果找不到,则查找名为“1”的ivar(这不是合法名称)对于ivar,但仍然如此,如果没有,它会尝试发送你尚未实现的-setValue:forUndefinedKey:
。
阅读有关键值编码的文档,并了解如何使您的KVC符合类。