在Objective c中实现键值编码

时间:2012-05-23 10:19:12

标签: iphone objective-c ipad

我是时候在我的程序中实现键值编码,所以我对它不太满意。我有控制器类,其中解析方法在启动文档中实现我已初始化对象和键。 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

这是什么原因。是否遗漏了某些东西或一切都出错了?

3 个答案:

答案 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符合类。