Objective-c:类内的方法调用仍然使用选择器或纯调用吗?
我正在比较不同的编程语言和开发平台。 Objective-C 和其他语言之间的一个重要区别是它使用选择器、消息,因此每次都会调用 objc_msgSend,跨越共享库的边界,因此引入了可测量的开销,以及 objc_msgSend 的进一步开销(在缓存情况下很少)内部功能,如下所述: http://www.mulle-kybernetik.com/artikel/Optimization/opti -3.html 我不是专家,所以我必须相信在这个论坛上找到的这篇文章。 在苹果官方指南上,我发现“点语法”只是“语法糖”,即使用相同的方法调用机制。 问题:我想知道是否在类实例内部执行纯调用,在这种情况下调用 objc_msgSend 会很浪费。即从同一类实例的方法调用一个类实例的方法时。 谢谢
I am comparing different programming languages and development platforms. One important difference between objective-c and other languages is that it uses selectors, messages, so calling objc_msgSend every time, crossing the boundary of shared library, so introducing a measurable overhead, plus further overhead (little in the cached case) for the objc_msgSend internal functioning, like explained here:
http://www.mulle-kybernetik.com/artikel/Optimization/opti-3.html
I am not an expert so I have to trust this article, found on this forum.
On official Apple guide I find that "dot syntax" is just "syntactic sugar", that is the same method calling mechanism is used.
Question: I would like to know if, instead, pure calls are performed inside a class instance, where it would be a waste to call objc_msgSend. That is when one class instance's method is called from a same class instance's method.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
所有 Objective-C 方法调用都使用 obj_msgSend。这是因为代码不知道真正的类,即
self
。即:它可以是具有另一个实现的子类,甚至可以是远程计算机通过 xmlrpc 实现的方法的代理。AFAIK,如果您知道要经常向对象 Y 发送消息 X,则可以通过获取给定对象的选择器的实现来自行优化。
All objective-C method calls use obj_msgSend. This is because the code doesn't know the actual real class that is
self
. ie: it could be a subclass with another implementation, or even a proxy for a method that is implement by a remote machine via xmlrpc for example.AFAIK the you can optimise things yourself by grabbing the implementation of a selector for a given object if you know you're going to send message X to object Y often.
它仍然通过 objc_msgSend 和变体使用动态调度。
理想情况下,将为 objc 类型生成类似于 JIT 的东西。
与 objc 不同,C++ 编译器可以使用静态分派来调用 C++ 类型,当它可以确定类型时,这些类型被标记为虚拟。
无论如何,有很多方法可以优化——您可以从在 c++ 中实现开始,然后在真正方便的地方使用 objc...但我不确定您到底想要完成什么。
it still uses dynamic dispatch via objc_msgSend and variants.
ideally, something similar to a JIT would be produced for objc types.
unlike objc, a c++ compiler can use static dispatch for calls to c++ types which are marked virtual when it can determine the type.
at any rate, there are many ways to optimize -- you could begin by implementing in c++, and then use objc where it's really handy... but i'm not sure what exactly you're trying to accomplish.
在假设的 OOP 语言中考虑这种情况:
现在
假设您有一个
B
实例,并调用do_something
:应该
b
打印A
还是B
?如果在do_something
的实现中对say_something
的调用经过vtable
(在 C++ 中)或obj_msgSend
(在Obj-C),它将打印B
,但如果编译器决定调用同一类中的方法应该调用同一类中的方法,它将打印A.
哪个是可取的取决于具体情况。因此,在 C++ 中,您可以通过将成员函数标记为
virtual
或不标记来进行选择。在 Objective-C 中,每个方法都是虚拟的。
因此,即使在 C++ 中,您建议的优化也不会针对虚拟方法进行。我不会说没有虚拟方法的语言是正确的 OOP 语言。
不管怎样,现在您可能担心它会降低 Obj-C 应用程序的性能。苹果知道其中的危险,因此他们进行了很多很多的优化。例如,在最近的运行时中,
objc_msgSend
位于固定地址,因此您不需要首先穿过共享库边界。Mulle-Kybernetic 文章也不错,但请注意,它非常过时:它已经是十年前的事了,对于这个行业来说,这是史前时代。您可以在 bbum 的博文 或 Hamster 的博客文章。
如果您正在编写管理 UI 的代码,那么使用标准消息传递(即在幕后的 objc_msgSend )就完全足够了。它甚至在移动设备上也运行得非常流畅!因此,不要通过获取
IMP
等来进行过早的优化,除非在测量代码性能后证明这是绝对必要的。如果您正在编写涉及数万个粒子移动的计算密集型代码,是的,我建议不要使用 Obj-C 消息传递框架。在这种情况下,只需编写 C 代码(始终可以在 Objective-C 中使用)或 C++ 代码(可以在 Objective-C++ 中使用。)
Consider this situation in a hypothetical OOP language:
and
Now suppose you have an instance of
B
, and calldo_something
:Should
b
printA
orB
? If the call tosay_something
in the implementation ofdo_something
goes through thevtable
(in C++) orobj_msgSend
(in Obj-C), it will printB
, but if the compiler decides a call to a method in the same class should call to the method in the same class, it will printA
.Which is desirable depends on the situation. So, in C++, you can have a choice, by marking a member function
virtual
or not.In Objective-C, every method is virtual.
So, even in C++, the optimization you suggested is not done to virtual methods. I won't say a language without virtual methods a proper OOP language.
Anyway, now you might worry it would degrade the performance of an Obj-C app. Apple knows the danger, so they have lots and lots of optimization. For example, in a recent runtime,
objc_msgSend
lives at a fixed address, so that you don't first need to go through the shared-library boundary.The Mulle-Kybernetic article was also nice, but note also it's very dated: it's whopping ten years ago, which is in this business a pre-historic times. You can read about recent optimizations put in to the implementation of
objc_msgSend
in bbum's blog posts or Hamster's blog posts.If you are writing codes managing UI, using the standard messaging (i.e.
objc_msgSend
behind the scenes) is perfectly adequate. It even works very smoothly on mobile devices! So, don't do a premature optimization by getting theIMP
, etc., until it turns out to be absolutely necessary after measuring the performance of a code.If you're writing a calculation-intensive code involving, say, tens of thousands of particles moving, yes I would advice against using the Obj-C messaging framework. In that case, just simply write a C code (which can always be used in Objective-C ) or C++ code (which can be used in Objective-C++.)