所以我正在研究obj-c中的一些东西(我宁愿不说什么),我需要能够在任意变量的任意对象上调用任意方法。前两个很容易做到,但我不确定如何做变量参数。需要明确的是,关于接收变量参数的函数/方法,不,关于发送它们。我找到了两种方法:Objective-c运行时的objc_msgSendv(及其变体)和NSInvocation。 NSInvocation似乎更容易,更像是'最佳实践',但objc_msgSendv听起来应该更快,我需要做很多次,每次都有完全不同的消息。我应该选择哪一个? objc_msgSendv禁忌有充分理由吗? (文档说不要调用objc_msgsend函数。)
P.S。我知道所有参数的类型,而不是所有参数都是id-s
另外,(不是主要问题的一部分)似乎没有办法从objc_msgSendv发送消息super,但似乎没有办法在NSInvocation中这样做,所以任何帮助那也很棒。
答案 0 :(得分:3)
objc_msgSendv
已被弃用;在64位Mac OS X应用程序中完全不可用。所以,不管怎样,不要使用它。
真正的问题是你是否知道在编译时设置的参数。如果是,请使用objc_msgSend
(或适当的变体)。
如果没有,那么您将不得不使用某种机制将参数编码为符合特定目标体系结构的C ABI的调用。 NSInvocation
是最容易实现的方法,但你确实存在开销。
你可以下拉到libffi
以获得效率,但是仍然需要大量的开销来构建自己的调用,而不是让编译器编译一些代码。
如果你有一组有限的参数和返回类型的组合,你可以编译一堆trampoline函数并使用它们。
实际上,真正的问题是“你想做什么?”你所描述的是相当不典型的。并不是说你可能没有一个很好的理由,只要不管它是什么都非常有趣(无论如何都是对我来说)!
答案 1 :(得分:1)
注意过早优化。我将从更高级别的功能(NSInvocation)开始,因为它更容易进行单元测试,代码和调试。然后进行测量。仅当您的测量显示NSInvocations内部和周围花费大量时间(例如准备它们)时,才转移到较低级别的功能(objc_msgSendv)。否则,即使objc_msgSendv更快,您也不会收到任何可观察到的好处,代价是难以维护的代码。