Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is "super" in Objective-C? ( self != super )?

I've read the question below, and the story SEEMS simple:

What exactly is super in Objective-C?

Yet ...

- (id) init
{
    NSLog(@"self=%p, super=%p", self, super);
}

That prints out "self=0xa83dc50, super=0xbfffe8d0". The addresses are NOT THE SAME???!?!?

That second address seems like a "special value" or something. What does it mean?

Thanks to bbum for pointing out that this value is the stack address of a special struct used by the compiler to implement the "super" behavior.


I can call [super init] and the call seems to work, or at least, nothing explodes ... not immediately. Calling [((id)0xbfffe8d0) init] fails hard with EXC_BAD_ACCESS.

Then there is the REALLY WEIRD part..... I've got a piece of code that for no explainable reason throws a "NSGenericException: collection was mutated while being enumerated" exception. Inside a DIFFERENT object (basically a wrapper that has a pointer to the NSEnumerator), commenting out the call to "[super init]" causes the exception to not happen. If I could, I'd put out a $$$ reward for an answer to THAT mind-bender.

"id sups = (id)0xbfffe8d0" ... that also leads to "collection is modified." ... WTF? Ok, so I'm posting a 2nd question for that bizzariotity ...


I originally came here with one of those "bizarre symtoms" bugs, that turned out to be entirely unrelated (typical for such things): Does casting an address to (id) have side-effects??? Is Address 0xbfffe8d0 special? (fixed: issue was with _NSCallStackArray)

However, the content above the line is still valid, and the response still excellent. Read it if you want to understand ObjC just a little bit deeper.

like image 837
Dave Dopson Avatar asked Apr 01 '12 02:04

Dave Dopson


1 Answers

You are messing with the man behind the curtain and he is punishing you for it... :)

super is a bit of compiler magic, really. When you say [super doSomething], the compiler will emit a call to objc_msgSendSuper() instead of objc_msgSend(). Most of the time -- there are some special cases.

In general, you should treat super as only a target for method calls. It should never be stored anywhere and should never be considered anything but that target expression for messaging.

In fact, uses of super that involve storage should likely be flagged by the compiler.

In terms of your bug, that sounds an awful lot like there is either corruption of memory, an over-release, and/or concurrency going on. You'll need to provide more code related to the enumeration and other relevant code to deduce further.

like image 177
bbum Avatar answered Sep 23 '22 05:09

bbum