【问题标题】:Objective-C uses dynamic binding, but how?Objective-C 使用动态绑定,但如何?
【发布时间】:2009-11-08 16:43:53
【问题描述】:

我知道 Objective-C 对所有方法调用都使用动态绑定。这是如何实施的? Objective-c 是否在编译前“转换为 C 代码”,并且对所有内容都使用 (void*) 指针?

【问题讨论】:

  • objective-c 运行时是开源的,顺便说一句。它使阅读变得有趣。 objc_msgSend() 实际上是一个小程序集,它使用尾调用优化来进行调度,以消除调用时重写堆栈帧的需要。相当快。

标签: objective-c dynamic-binding


【解决方案1】:

从概念上讲,发生的事情是有一个调度程序库(通常称为 Objective C 运行时),编译器会转换如下内容:

[myObject myMethodWithArg:a andArg:b ];

进入

//Not exactly correct, but close enough for this
objc_msgSend(myObject, "myMethodWithArg:andArg:", a, b);

然后运行时处理所有绑定和分派,找到合适的函数,并使用这些参数调用它。简单地说,您可以将其视为哈希查找。当然,实际情况要复杂得多。

还有很多与方法签名等相关的问题(C 不对类型进行编码,因此运行时需要处理它)。

【讨论】:

    【解决方案2】:

    每个Objective C 方法都在“底层”实现为(实际上)一个C 函数。该方法具有与之关联的消息(文本字符串),并且该类具有将消息字符串与 C 函数匹配的查找表。因此,当您调用一个 Objective C 方法时,真正发生的事情是您向对象发送一个消息字符串,然后该对象在其类的方法查找表中查找关联的 C 函数并运行它。

    Objective C 中还有更多内容,例如对象如何通过转发它们来处理它们不理解的消息,它们如何缓存消息到方法的查找等等,但这是基础。

    C++ 是类似的,除了这个类没有消息表,它有一个叫做“vtable”的东西,你调用一个方法不是通过文本字符串,而是通过它在 vtable 中的偏移量。这是静态绑定的一种形式,可以在一定程度上加快执行速度,但不如动态绑定灵活。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      • 2011-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多