目标C消息调度机制 [英] Objective C message dispatch mechanism

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

问题描述

我只是盯着玩Objective C(编写玩具iPhone应用程序),并且对用于分发消息的底层机制感到好奇.我对C ++中的虚函数通常是如何实现的以及相对于静态或非虚方法调用的成本有很好的了解,但是我对Obj-C没有任何了解消息发送方式的背景.浏览时发现宽松的基准它提到了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消息.显示在 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的

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

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 ++中的静态类方法)相同,或者它们还有其他功能吗?

类对象以与类实例类似的方式处理方法发送.每个类对象都有一个对象,该对象在称为metaclass的对象中存储自己的 class 方法.类对象有自己的指向其元类对象的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. 重复此过程,直到找到方法或到达根元类为止,并引发异常.
  1. The dispatch system follows the class object's isa pointer to the metaclass object
  2. The metaclass object's method table is searched for the class method.
  3. If not found, the search continues to the metaclass object's superclass, where the search continues.
  4. This process repeats until either the method is found, or until it gets to the root metaclass, and an exception is thrown.

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

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