0

我是时候在我的程序中实现键值编码了,所以我对它不太满意。我有控制器类,其中解析方法在开始文档中实现,我已经初始化了对象和键。Universal 类的所有数据成员都是类型 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"];

我在结束元素方法中设置数据成员的值:

         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

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

4

3 回答 3

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对象的属性。那将是多余的。

我怀疑你认为你在这里建立了同义词或别名——你正在将键“1”映射到 property datamember1。这是不正确的。该-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 术语解释您正在尝试做什么。您尝试更改哪些属性(如果是)?你想赋予他们什么价值?您将如何仅使用普通的 setter 和 getter 来做到这一点?

后来,您发布了以下代码:

    id temp1=[univ valueForKey:@"1"];
    temp1=strVal;
    [resultArray addObject:univ];

同样,这很奇怪且令人困惑。我怀疑您正在尝试更改 上的属性值univ,但这不是该代码完成的任务,即使它可以工作。第一行尝试获取univ对象的属性值,其中属性的名称为“1”。这不是属性的有效名称。无论如何,它将检索到的值存储到局部变量temp1中。第二行简单地丢弃第一行的结果并将不同的值存储到局部temp1变量中。该temp1变量独立于univ对象,即使之前它正在存储从univ对象检索到的结果。改变temp1不能改变univ(尽管传递指向的对象temp1可以更改该对象,并且它也可能由 ) 指向univ

在我看来,您还没有准备好使用键值编码。您需要更好地了解基础知识。此外,几乎不需要将键值编码与静态的、编译时已知的键一起使用。当您在编译时不知道该属性的名称但您将在运行时将名称作为数据时,键值编码用于动态访问对象的属性。

于 2012-05-23T10:45:40.893 回答
0

请阅读 Apple 文档中有关确保 KVC 合规性的部分。

它是这样说的:

对于属性或一对一关系的属性,这要求您的类:

  • 实现一个名为 -<key>、-is<Key> 的方法,或者有一个实例变量 <key> 或 _<key>。
  • 如果属性是可变的,那么它也应该实现 -set<Key>:。

合成一个属性也有资格实现一个方法,所以你的Universal类需要一个名为12等)的方法和另一个被调用的方法set1:,它当然没有,因为方法名称以数字开头是非法的。

于 2012-05-23T10:28:42.903 回答
0

您还没有为要访问的键实现 setter 和 getter,也没有实现-setValue:forUndefinedKey:.

在运行时,NSObject 的实现-setValue:forKey:查找名为“set1:”的方法,如果找不到,它会查找名为“1”的 ivar(这不是 ivar 的合法名称,但仍然如此),如果失败,它会尝试发送-setValue:forUndefinedKey:您尚未实现的。

阅读有关键值编码的文档,并了解如何使您的类符合 KVC。

于 2012-05-23T10:30:47.553 回答