Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

objective c - what was the second parameter in "id (*IMP)(id, SEL, ...) " used for?

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The signature of objc_msgSend() is:

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];

That will be compiled as if it were:

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

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;

Exactly equivalent to this C function:

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

The answer is speed speed speed.

Speed

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() uses the object and the _cmd to look up the implementation of the method and then, quite literally, jumps to that implementation.

Very fast. Stack frame untouched.

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.

*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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...