Objective-c:类内的方法调用仍然使用选择器或纯调用吗?

发布于 2024-11-24 07:26:15 字数 449 浏览 2 评论 0原文

我正在比较不同的编程语言和开发平台。 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

黑白记忆 2024-12-01 07:26:36

所有 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.

小姐丶请自重 2024-12-01 07:26:36

它仍然通过 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.

东京女 2024-12-01 07:26:35

在假设的 OOP 语言中考虑这种情况:

class A {
     say_something(){
         print("A!")
     }
     do_something(){
         say_something()
     }
}

现在

class B : extends A {
     say_something(){
         print("B!")
     }
}

假设您有一个 B 实例,并调用 do_something

B b;
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:

class A {
     say_something(){
         print("A!")
     }
     do_something(){
         say_something()
     }
}

and

class B : extends A {
     say_something(){
         print("B!")
     }
}

Now suppose you have an instance of B, and call do_something :

B b;
b.do_something();

Should b print A or B? If the call to say_something in the implementation of do_something goes through the vtable (in C++) or obj_msgSend (in Obj-C), it will print B, 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 print A.

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 the IMP, 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++.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文