Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 避免objmsg函数开销?_Objective C - Fatal编程技术网

Objective c 避免objmsg函数开销?

Objective c 避免objmsg函数开销?,objective-c,Objective C,我们是否可以通过使用sel和imp means选择器和实现指针来避免objmsg函数开销。请告诉我们如何避免它?//首先,访问您感兴趣的选择器(示例) // first, access the SELector you're interested in (example) SEL sel = @selector(<#SOMETHING#>); // this is the definition of IMP id (*IMP)(id, SEL, ...); SEL=@select

我们是否可以通过使用sel和imp means选择器和实现指针来避免objmsg函数开销。请告诉我们如何避免它?

//首先,访问您感兴趣的选择器(示例)
// first, access the SELector you're interested in (example)
SEL sel = @selector(<#SOMETHING#>);

// this is the definition of IMP
id (*IMP)(id, SEL, ...);
SEL=@selector(); //这就是IMP的定义 id(*IMP)(id、SEL等);
使用以下命令访问特定类实例的IMP:
+(IMP)instanceMethodForSelector:(SEL)一个选择器

理想情况下,您将把instanceMethodForSelector:的结果强制转换为所调用函数的精确的类型定义,以便编译器能够正确获得sig

一旦有了对象SEL和IMP,就可以将IMP用作普通的C函数指针


其中,IMP函数返回的第一条消息是对象(
self
),第二个参数是选择器(
\u cmd
)。这是两个隐藏的objc参数。

我假设您的需求是分析的结果,而不是过早优化的情况

1) 您可以获取方法的实现(参见Justin的答案)。详细说明-在
objc\u msgSend
中没有太多开销。大多数情况下,它会检查
self
nil
值,在缓存中搜索IMP并对IMP()执行尾部调用。如果您想保存这几条说明,那么


2) 。。。从一开始就用C编写函数。这是一个更具可读性和可靠性的解决方案。

这个问题唯一严肃的答案是

使用Objective-C以外的东西


老实说,任何避免obj_msg_send()
的方法都是脆弱的,每次调用都可能为您节省纳秒。如果您有一个非常短的函数,并且经常被调用,那么您可能应该使用C来重新实现该函数。在几乎所有其他情况下,这都不值得费心。

在过去(10.3/10.4),我能够将耗时的数据搜索速度提高一倍。。。嗯,很多。让我们知道数字,如果你实现这个。我已经挖掘了一个有趣的文章(带有测试)的主题:IMP缓存(在Leopard)比ObjcMsGeMeX快7倍,而C++动态调度比IMP缓存慢1.5。当然,C或C++中的静态调度应该等于或优于IMP缓存(假设它没有内联)。我记得我在cocoa列表上为某人辩护,因为他想使用C来避免开销(在过去)。在那次对话中,“如果objc_msgSend出现在profiling中…”出现了(cont)(cont),而我在讨论中提出的许多观点是可以完全忽略函数/方法调用。。。在C++编写的GUI程序中,ObjcIsMgStand(包括变量)可以占用大约2%到7%的执行时间。在执行的上下文中,这相当于一个“相当温暖的点”——如果你的应用程序必须是最优的,那么objc对动态性及其运行时的使用是相当有限的。此外,它不应用于实时环境(如音频)。简而言之,如果使用C或C++而不是Objc,有很多东西可以获得(WRT性能)。获得方法实现并直接调用它是根据苹果的官方文档和合法API,所以它绝对没有什么脆弱性。这与obj_msg_send()的内部操作是一样的。对于一个名为1MIO time的操作,每次调用节省1ns可以为您节省1ms,这可能非常关键,如果您执行动画之类的操作,并且希望达到60fps(这意味着您只有16.6ms的时间来计算和渲染下一帧,因此1ms已经是可用时间的1/16,您不想白白浪费这些时间)@Mecki您忽略了一个事实,即在运行时可以将不同的函数与选择器关联(例如,请参见键值观察)。除非您确定不会发生这种情况,否则不应该这样做。使用KVO时,
methodForSelector:
仍将为您提供正确的函数指针(带有KVO的指针)。您只是不能将其结果缓存到当前方法范围之外,除非您确定没有任何代码会导致IMP更改。苹果将在内部缓存结果,但他们也会在需要时正确刷新缓存(你不能,因为你的代码无法知道何时需要刷新)。但苹果公司正式推荐这种方法,例如,为了加快循环速度,请参阅查找“获取方法地址”。Obj-C方法调用的速度大约是C函数调用的5倍(13个CPU周期),请参阅:但这只是因为苹果公司本身对IMP指针进行了积极的缓存。第一次调用方法或刷新缓存后,速度可能会慢得多。尽管如此,这意味着通过完全避免查找,您可以进行5倍的调用,并且根本不会影响总运行时间。和往常一样,这取决于你的应用程序在做什么,对于90%的应用程序来说,这可能没有什么区别。