ObjC中的#typedef和KVC

时间:2009-10-16 07:09:01

标签: objective-c typedef key-value-coding

我有一个看起来像这样的课程:

@interface Properties : NSObject {
@private
    NSNumber* prop1;
    NSNumberBool* prop2;
    //etc

其中NSNumberBool是typedef:

// in MyApp_Prefix.pch
typedef NSNumber NSNumberBool;

我拥有所有必需的@property和@synthesize声明来制作prop1和prop2属性。

所有编译和工作正常,直到我尝试通过[myProperties valueForKey:@“prop2”]访问prop2。这给了我一个“类不符合键值”的错误。但是,许多类似的调用工作正常:

myProperties.prop2; //works
[myProperties prop2]; //works
[myProperties valueForKey:@"prop1"]; //works
[myProperties valueForKey:@"prop2"] // throws NSUnknownKeyException ??

这里发生了什么,我该如何解决?

谢谢,

4 个答案:

答案 0 :(得分:5)

从编译示例并在其上发出class-dump,看来typedef已变为

struct NSNumber {
    Class _field1;
};

@interface Properties : NSObject
{
    NSNumber *prop1;
    struct NSNumber *prop2;
}

将typedef更改为此似乎可以正常工作,但可能并不完全符合您的要求。

#define NSNumberBool NSNumber

答案 1 :(得分:5)

我怀疑这是typedef与encode方法交互的方式的问题。

我相信typedef仍然是一个纯粹的C关键字,实际上恰好只使用Objective-C“类型”,因为它们恰好是作为结构实现的。

因此,当你将NSNumber输入到NSNumberBool时,它适用于方法调用(和点语法属性)但是(假设我的理论是正确的),中断编码不能告诉NSNumberBool和NSNumber是相同的类型。< / p>

我有兴趣看看有什么更了解的人说。

答案 2 :(得分:2)

这是一个很老的帖子,但我在寻找这个问题的解决方案时来到了它,这很好地通过Objective-C 2.0 @compatibility_alias指令解决了。这允许你写:

@compatibility_alias NSNumberBool NSNumber;

并为NSNumber创建了一个别名。 KVO与它完美配合。

在目前接受的答案中,这具有类型安全的巨大好处。

答案 3 :(得分:1)

与nall的答案类似,我也尝试过类转储。我找到了一个有趣的,如果丑陋的解决方法。以下代码:

typedef NSNumber* NSNumberBoolPtr;

@interface Test : NSObject {
    NSNumber *real;
    NSNumberBoolPtr poser;
}

class-dumps to:

@interface Test : NSObject
{
    NSNumber *real;
    NSNumber *poser;
}

@end

同样,不完全是你想要的,但你会得到编译器时间检查没有NSNumbers和NSNumberBools混合(这是我首先假设typedef的原因)。