为什么属性在编译期间需要显式输入?

时间:2011-01-13 07:38:01

标签: objective-c properties

使用属性语法进行编译需要在编译时知道接收器的类型。我可能听不懂,但考虑到Objective-C是一种动态语言,这似乎是一个破碎或不完整的编译器实现。

属性“comment”定义为:

@property (nonatomic, retain) NSString *comment;

并与:

合成
@synthesize comment;

“document”是符合以下几个类之一的实例:

@protocol DocumentComment <NSObject>

@property (nonatomic, retain) NSString *comment;

@end

并简单地声明为:

id document;

使用以下属性语法时:

stringObject = document.comment;    

gcc:

生成以下错误
error: request for member 'comment' in something not a structure or union

但是,以下等效的接收方法语法,在没有警告或错误的情况下编译,并且在运行时正常工作:

stringObject = [document comment];  

我不明白为什么属性要求在编译时知道接收器的类型。有什么我想念的吗?我只是使用后一种语法来避免接收对象具有动态类型的情况下的错误。属性似乎半生不熟。

2 个答案:

答案 0 :(得分:4)

编译属性访问权限需要知道如何将属性名称转换为正确的getter / setter名称。在不知道接收器的类型的情况下,编译器不可能知道调用getter / setter的内容,因为属性可能已将名称覆盖为其声明的一部分,如下所示:

@property (nonatomic, retain, getter=myComment) NSString *comment;

如果编译器继续为您的无类型示例生成代码,它将生成[document comment],它将在运行时失败,因为正确生成的代码实际上是[document myComment]

答案 1 :(得分:3)

凯文指出了其中一个症状。

在设计属性时,非常具体的决定 not 以支持id作为点语法的目标。除了凯文指出的模棱两可之外,还希望避免与(id)接收器相关的所有歧义的愿望。

一般而言,完全不合格的id的使用既不合乎要求,也不积极劝阻。在使用该语言创建新功能时,不支持id会阻止新功能中扩散的脆弱编码模式。