objective-c:类内部的方法调用仍然使用选择器还是纯调用



我正在比较不同的编程语言和开发平台。objective-c和其他语言之间的一个重要区别是,它使用选择器、消息,因此每次都调用objc_msgSend,跨越共享库的边界,因此引入了可测量的开销,再加上objc_mgsSend内部函数的额外开销(在缓存的情况下很少(,如下所述:http://www.mulle-kybernetik.com/artikel/Optimization/opti-3.html我不是专家,所以我必须相信这个论坛上的这篇文章。在苹果官方指南上,我发现"点语法"只是"语法糖",也就是说使用了相同的方法调用机制。问题:我想知道是否在类实例内执行纯调用,在类实例中调用objc_msgSend是一种浪费。也就是说,从同一个类实例的方法调用一个类示例的方法。感谢

在假设的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的博客文章中阅读最近对objc_msgSend实现的优化。

如果您正在编写管理UI的代码,那么使用标准消息传递(即objc_msgSend幕后(就足够了。它甚至可以在移动设备上非常流畅地工作!因此,不要通过获取IMP等来过早地进行优化,直到在测量代码性能后证明这是绝对必要的。

如果你正在编写一个计算密集型代码,比如说,涉及成千上万的粒子移动,是的,我建议不要使用Obj-C消息传递框架。在这种情况下,只需编写一个C代码(它总是可以在Objective-C中使用(或C++代码(它可以在Objective C++中使用(

所有objective-C方法调用都使用obj_msgSend。这是因为代码不知道实际的类self。ie:它可以是具有另一个实现的子类,甚至可以是远程机器通过xmlrpc实现的方法的代理。

如果您知道要经常向对象Y发送消息X,那么您可以通过获取给定对象的选择器的实现来优化自己。

它仍然通过objc_msgSend和变体使用动态调度。

理想情况下,将为objc类型生成类似于JIT的东西。

与objc不同,c++编译器可以在确定类型时,对标记为virtual的c++类型的调用使用静态调度。

无论如何,有很多优化方法——您可以从用c++实现开始,然后在真正方便的地方使用objc。。。但我不确定你到底想实现什么。

相关内容

  • 没有找到相关文章

最新更新