The snippet below is taken from Apple's ObjC runtime (libobjc) source code. I wonder what this means exactly. (Not very google-able, sorry)
// HACK -- the use of these functions must be after the @implementation
id bypass_msgSend_retain(NSObject *obj) asm("-[NSObject retain]");
void bypass_msgSend_release(NSObject *obj) asm("-[NSObject release]");
id bypass_msgSend_autorelease(NSObject *obj) asm("-[NSObject autorelease]");
Update:
Here is what a call to bypass_msgSend_release() generates:
movl -4(%ebp), %eax
movl %eax, (%esp)
calll "-[NSObject release]"
Here's the actual implementation of
retainfrom later in the file:So if it's a tagged pointer, do nothing. Fair enough, that means it doesn't actually relate to anything on the heap and there is no retain count.
Otherwise in the old days they'd just message
retainto the object. Now they messageretainto the object if it has been noted to contain a customretain(no doubt not something the old runtime would record, hence the version check) otherwise they use the bypass method.The bypass appears to call directly into the known address of
[NSObject retain].So my guess? It's a speed optimisation. If you can tell that there's no custom retain and, in effect, jump straight to the
IMPthen you save the cost of the dynamic dispatch. Given that the compiler now throws in the C calls automatically under ARC (notably not the Objective-C calls) that means you never go into the more expensive stuff.