7

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

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

其中 NSNumberBool 是 typedef:

// in MyApp_Prefix.pch
typedef NSNumber NSNumberBool;

我拥有创建 prop1 和 prop2 属性所需的所有 @property 和 @synthesize 声明。

在我尝试通过 [myProperties valueForKey:@"prop2"] 访问 prop2 之前,一切都编译并运行良好。这给了我一个“类不符合键值”错误。但是,许多类似的调用都可以正常工作:

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

这是怎么回事,我该如何解决?

谢谢,

4

4 回答 4

5

从编译您的示例并在其上发出类转储,看来 typedef 正在变成

struct NSNumber {
    Class _field1;
};

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

将 typedef 更改为此似乎可以正常工作,尽管可能不完全是您想要的。

#define NSNumberBool NSNumber
于 2009-10-16T07:32:46.197 回答
5

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

我相信 typedef 仍然是一个纯 C 关键字,并且通常只碰巧与 Objective-C“类型”一起工作,因为它们碰巧被实现为结构。

因此,当您将 NSNumber 类型定义为 NSNumberBool 时,它对于方法调用(和点语法属性)工作得很好,但是(假设我的理论是正确的),会破坏无法判断 NSNumberBool 和 NSNumber 是同一类型的编码。

我很想看看知道的人怎么说。

于 2009-10-16T07:36:09.877 回答
2

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

@compatibility_alias NSNumberBool NSNumber;

并为NSNumber. KVO 与它完美配合。

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

于 2016-07-25T10:26:44.403 回答
1

与nall的回答类似,我也尝试了class-dump。我确实找到了一个有趣的,如果丑陋的解决方法。以下代码:

typedef NSNumber* NSNumberBoolPtr;

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

类转储到:

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

@end

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

于 2009-11-16T19:50:42.907 回答