"id(* IMP)(id,SEL,...)"中的第二个参数是什么?用于? [英] what was the second parameter in "id (*IMP)(id, SEL, ...) " used for?

查看:262
本文介绍了"id(* IMP)(id,SEL,...)"中的第二个参数是什么?用于?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题正如标题所说.显然,第一个参数用于此指针,有点象c ++.第二个参数又如何呢?让你感动.

my question as the title says.obviously, the first parameter was used for this pointer , in some taste of c++.what about the second one? thak you.

推荐答案

objc_msgSend()的签名是:

id objc_msgSend(id self, SEL op, ...);

每个方法调用都被编译为对该函数的调用.即,如果您致电:

Every method call is compiled down to a call to this function. I.e., if you call:

[anArray objectAtIndex:42];

它将被编译为:

objc_msgSend(anArray, @selector(objectAtIndex:), 42);

现在,对于您的问题,为什么将方法编译为以SEL作为第二个参数的函数.或者,更具体地说,为什么使用这种方法:

Now, to your question, why do methods get compiled down to a function that has the SEL as the second argument. Or, more specifically, why is this method:

- (id)objectAtIndex:(NSUInteger)index;

完全等同于此C函数:

id object_at_index(id object, SEL _cmd, NSUInteger index);

答案是速度速度 速度.

具体而言,通过执行此操作,objc_msgSend()无需重写堆栈框架*,并且还可以使用尾部调用优化直接跳转到方法调用.这就是为什么您永远不会在调试器的回溯中看到objc_msgSend()的原因(除了在信使中实际崩溃/中断的时间之外).

Specifically, by doing this, then objc_msgSend() never has to rewrite the stack frame* and it can also use a tail call optimization to jump directly to the method invocation. This is the same reason why you never see objc_msgSend() in backtraces in the debugger (save for when you actually crash/break in the messenger).

objc_msgSend()使用object_cmd查找该方法的实现,然后,从字面上看,跳转到该实现.

objc_msgSend() uses the object and the _cmd to look up the implementation of the method and then, quite literally, jumps to that implementation.

很快.堆栈框未触碰.

并且,正如其他人所述,由于各种原因,在方法实现中使用_cmd可能很方便.同样,这也意味着Messenger可以通过NSInvocation等完成整洁的技巧,例如代理支持.

And, as others have stated, having _cmd around in the method implementation can be handy for a variety of reasons. As well, it also means that the messenger can do neat tricks like proxy support via NSInvocation and the like.

*重写堆栈框架可能非常复杂且昂贵.某些时候,某些参数可能在寄存器中,等等...所有与体系结构有关的ABI缺陷.编写imp_implementationWithBlock()之类的最大挑战之一就是弄清楚如何做到不触及堆栈,因为这样做会太慢,太to肿以致于无法生存.

*rewriting the stack frame can be insanely complex and expensive. Some of the arguments might be in registers some of the time, etc... All architecture dependent ABI nastiness. One of the biggest challenges to writing things like imp_implementationWithBlock() was figuring out how to do so without touching the stack because doing so would have been too slow and too bloated to be viable.

这篇关于"id(* IMP)(id,SEL,...)"中的第二个参数是什么?用于?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆