Objective-C对象类型如何也是一个类?

时间:2018-01-16 20:52:39

标签: objective-c class types compiler-construction

Objective-C对象类型(它是一个结构,对吗?)如何也是一个类(它是一个结构*)?

消息传递括号中的NSObject实际上是objc_class结构,它有一个指向元类的指针,其中存储了类方法吗?如果是这样,同一个术语如何也可以作为分配给anObject的类型?

如:NSObject * anObject = [NSObject alloc] init];

3 个答案:

答案 0 :(得分:0)

你可能在想这个;它取决于语言的定义。语言可以在不同的上下文中使用相同的语法元素来表示不同的语义

子表达式:

[NSObject alloc]

表示“将alloc消息发送到类型NSObject的类对象。所以NSObject用于标识类对象。而声明:

NSObject *anObject;

表示“分配正确大小的变量以保存NSObject *类型的值,并为其指定名称anObject。因此NSObject用于标识类型。< / p>

这两种用法显然密切相关,因此使用类似的语法元素,但它们具有不同的语义

HTH

附录

如果有帮助,声明:

NSObject *anObject = [[NSObject alloc] init];
根据定义,

大致相当于:

Class objectClass = objc_getClass("NSObject");
NSObject *anObject = [[objectClass alloc] init];

但是使用额外的语言规范/编译时,要求NSObject必须是可访问类型而不仅仅是字符串中的字符("NSObject")。

答案 1 :(得分:0)

Objective-C对象不一定是struct。曾几何时他们(大部分)都是,但至少从十多年前的Objective-C 2.0开始,他们不可能。

最明显的例子:nil对象。它是一个接受任何消息并返回nil的对象。它不是结构。它在内存中不存在。

第二个最明显的例子:在64位运行时中,存储在标记指针中的任何东西都不是结构,因为表面上指针实际上并不指向任何东西。它是对象的价值。堆上没有任何东西。

存在各种其他例子;但是,除非你想要非常广泛地定义一个结构,以及任何意味着某些东西的位集合,否则对象不一定是结构。

NSObject中的[[NSObject alloc] init]是对NSObject的元类的单个实例的引用,它在内存中有某个表示。与任何其他对全局的引用一样,它将在您的二进制文件中存根,通常,实际地址将被动态链接器替换。

假设强联动和/或找到符号。如果你的链接很弱,那么如果没有NSObject,链接器就会放在对nil对象的引用中。

您可以同样执行[[NSClassFromString(@"NSObject") alloc] init],但效果略有不同:将尝试在运行时查找元类。因此,这不是编译器通常会生成的内容,但是由于运行时成本较低,它将允许继续发送消息,就像您静态地命名该类并进行弱链接一样。

答案 2 :(得分:0)

基本上,Objective-C中的括号语法有两个独立的语法案例:

[<expression> <selector and arguments>]

[<class name> <selector and arguments>]

虽然你可以[NSObject alloc],但像NSObject这样的类名在Objective-C中不是表达式 - 试图使用NSObject就好像它是其他地方的表达式一样在代码中会产生错误(这就是为什么当我们需要一个表达式来计算类对象的指针时,我们被迫写[NSObject class]的原因。相反,当你编写[NSObject alloc]时,它正在使用括号语法的第二种情况,其中前面的东西是类名,而不是表达式。

你可以想象当编译器编译括号语法的第二种情况时会发生什么,例如[NSObject alloc]它会将它转换为括号语法的第一种情况,但是对于表达式,它使用内部指针NSObject类对象,有点像[objc_getClass("NSObject") alloc],除了它不需要运行时查找,它在编译时直接链接值。

(顺便说一句,在Smalltalk,这是Objective-C的对象系统派生的地方,类名一个表达式(评估为类对象),所以在Smalltalk中发送消息的语法(除了没有括号几乎与Objective-C相同)并不需要上面两个独立的情况 - 第一个案例已经覆盖了第二个案例。我相信他们并不想要在创建Objective-C时创建类名表达式,因为具有相同的标识符既是类型又是表达式会导致C解析器出现问题。)