Objective C 消息分发机制 [英] Objective C message dispatch mechanism

查看:29
本文介绍了Objective C 消息分发机制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想玩玩 Objective C(编写玩具 iPhone 应用程序),我对用于发送消息的底层机制很好奇.我非常了解 C++ 中的虚函数通常是如何实现的,以及相对于静态或非虚方法调用的成本是多少,但我没有任何 Obj-C 背景来了解消息是如何发送的.浏览我发现 this 松散的基准和它提到 IMP 缓存消息比虚函数调用快,而虚函数调用又比标准消息发送快.

I am just staring to play around with Objective C (writing toy iPhone apps) and I am curious about the underlying mechanism used to dispatch messages. I have a good understanding of how virtual functions in C++ are generally implemented and what the costs are relative to a static or non-virtual method call, but I don't have any background with Obj-C to know how messages are sent. Browsing around I found this loose benchmark and it mentions IMP cached messages being faster than virtual function calls, which are in turn faster than a standard message send.

我不是要优化任何东西,只是更深入地了解消息是如何发送的.

I am not trying to optimize anything, just get deeper understanding of how exactly the messages get dispatched.

  • Obj-C 消息是如何发送的?
  • 实例方法指针是如何被缓存的,你(通常)能否通过阅读代码判断消息是否会被缓存?
  • 类方法本质上是否与 C 函数(或 C++ 中的静态类方法)相同,或者它们有更多的东西吗?

我知道其中一些问题可能依赖于实现",但只有一种实现才是真正重要的.

I know some of these questions may be 'implementation dependent' but there is only one implementation that really counts.

推荐答案

Obj-C 消息是如何调度的?

Objective-C 消息使用运行时的 objc_msgSend() 函数进行调度.显示在 Apple 文档中,该函数至少有 2 个参数:

Objective-C messages are dispatched using the runtime's objc_msgSend() function. Shown in the Apple docs, the function takes at least 2 arguments:

  1. 接收对象
  2. 消息的选择器
  3. [发送消息的可变参数列表.]

一个类的实例有一个 isa 指针,它是一个指向它们的类对象的指针.每个对象中方法的选择器都存储在类对象中的表"中,objc_msgSend() 函数跟随指向类对象的 isa 指针,指向找到这个表,并检查该方法是否在该类的表中.如果找不到,它会在类的超类的表中查找该方法.如果未找到,则继续沿对象树向上,直到找到该方法或到达根对象 (NSObject).此时抛出异常.

Instances of a class have an isa pointer, which is a pointer to their class object. The selectors of methods in each object are stored in a "table" in the class object, and the objc_msgSend() function follows the isa pointer to the class object, to the find this table, and checks whether the method is in the table for the class. If it cannot find it, it looks for the method in the table of the class's superclass. If not found, it continues up the object tree, until it either finds the method or gets to the root object (NSObject). At this point, an exception is thrown.

实例方法指针是如何被缓存的?(一般来说)你能通过阅读代码判断一条消息是否会被缓存吗?

来自 Apple 的 Objective-C 运行时指南 消息:

From Apple's Objective-C runtime guide on Messaging:

为了加快消息传递过程,运行时系统会在使用时缓存方法的选择器和地址.每个类都有一个单独的缓存,它可以包含继承方法以及类中定义的方法的选择器.在搜索调度表之前,消息传递例程首先检查接收对象的类的缓存(理论上使用过一次的方法可能会再次使用).如果方法选择器在缓存中,消息传递只比函数调用慢一点.一旦程序运行了足够长的时间来预热"它的缓存,它发送的几乎所有消息都会找到一个缓存方法.缓存会随着程序运行而动态增长以容纳新消息.

To speed the messaging process, the runtime system caches the selectors and addresses of methods as they are used. There’s a separate cache for each class, and it can contain selectors for inherited methods as well as for methods defined in the class. Before searching the dispatch tables, the messaging routine first checks the cache of the receiving object’s class (on the theory that a method that was used once may likely be used again). If the method selector is in the cache, messaging is only slightly slower than a function call. Once a program has been running long enough to "warm up" its caches, almost all the messages it sends find a cached method. Caches grow dynamically to accommodate new messages as the program runs.

如前所述,缓存在程序运行后就开始发生,在程序运行足够长的时间后,大部分方法调用都会通过缓存的方法运行.正如它也说的,缓存在方法被使用时发生,所以一条消息只在它被使用时被缓存.

As stated, caching starts to occur once the program is running, and after the program has been running long enough, most of the method calls will run through the cached method. As it also says, the caching occurs as the methods are used, so a message is only cached when it is used.

类方法与 C 函数(或 C++ 中的静态类方法)本质上是一样的,还是有更多的东西?

类对象以与类实例类似的方式处理方法分发.每个类对象都有一个对象,该对象将其自己的方法存储在一个称为元类的对象中.类对象有自己的 isa 指针指向它的元类对象,元类对象又具有超元类对象,它可以从中继承类对象.方法分派到类方法是这样的:

Class objects handle method despatch in a similar manner to that of instances of classes. Each class object has an object that stores its own class methods, in an object called a metaclass. The class object has its own isa pointer to its metaclass object, which in turn has super metaclass objects, which it can inherit class objects from. Method dispatch to class methods is as so:

  1. 调度系统遵循类对象的isa指针指向元类对象
  2. 在元类对象的方法表中搜索类方法.
  3. 如果未找到,则继续搜索元类对象的超类,在那里继续搜索.
  4. 重复这个过程,直到找到方法,或者直到它到达根元类,并抛出异常.

这篇关于Objective C 消息分发机制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆