Objective-C类是如何实现的?

时间:2014-03-27 19:33:57

标签: objective-c

我一直听说Objective-C类只是C Structs。任何人都可以更清楚地了解它们的实际实施方式吗?

3 个答案:

答案 0 :(得分:4)

  

我一直听说Objective-C类只是C Structs。

让我们先谈谈对象。

对象不是只是结构。它们具有特定布局的结构,Objective-C编译器和运行时可以理解它。运行时提供了许多实现消息传递等功能的C函数。编译器将Objective-C语法转换为对这些运行时函数的调用。所以,Objective-C的片段看起来像这样:

[foo bar:baz];

可能会被翻译成等效的C代码:

objc_msgSend(foo, sel_bar, baz);

其中sel_bar是与bar:对应的选择器。 foo是指向对象的指针,即形式的结构:

struct objc_object {
   Class isa;
};

可能会有其他实例变量捎带在该结构之上,因此foo的结构可能看起来像:

struct objc_object {
   Class isa;
   int a;
   float b;
   id c;
};

但是要成为运行时可以使用的对象,struct实际上只需要一个isa指针作为其第一个成员。这指向一个类对象,它定义foo所属的类。

现在,类也是一个对象 - 也就是说,它是一个以isa指针开头的结构。但是类有其他字段,包括超类,类名,实例变量列表,方法列表等。您可以在objc_class.h中查看实际定义。查看Objective-C Runtime Reference以查看对类进行操作的函数列表,以便更好地了解运行时如何操作该结构。

目前还有很多关于Objective-C如何从结构中创建对象的知识,但是Apple提供了一个解释它的完整文档,因此我只是引用您Objective-C Runtime Programming Guide

答案 1 :(得分:3)

直接实例变量的存储看起来很像C结构;通常它只是一个,你可以直接操纵结构而不是对象。那已被删除。

所以在结构中你将拥有:

  • isa指针,指向元类;
  • 分配对象到此元类'struct成员的开头的偏移量的记录(这就是如何避免脆弱的基类问题 - 在加载应用程序时适当地存储和加入大小);和
  • 所有直接实例变量的类似结构的字段。

在运行时的其他地方,至少还会有以下地图:

  • 每个支持的选择器的方法IMP的元类的元类;
  • 存储所有动态属性的实例;
  • 关联对象的实例;和
  • 也可能从实例到任何weak引用它。

此外,还有一个保留计数的哈希映射。保留计数仅在高于1时存储 - 隐含第一个保留。

很多例外是标记指针。 64位运行时允许将非常小的对象完全填充到指针中。所以指针是对象存储;运行时可以发现真实指针和秘密地是对象之间的差异,因为有效指针具有对齐要求。

答案 2 :(得分:-1)

Objective-C类实际上是一个对象本身。

这是关于这个主题的正确读物:http://www.cocoawithlove.com/2010/01/what-is-meta-class-in-objective-c.html