I have 2 classes A and B,B is inherited from A,A is inherited from NSObject.Class A has a function -(void)init:
- (void)init {
if (self = [super init]) {
NSLog(@"A");
}
return self;
}
B has:
- (id)init {
if (self = [super init]) {
NSLog(@"B");
}
return self;
}
After compilation I have “A” and “B” in my console,despite of condition in B “if (self = [super init])” can’t be true,cause its superclass init method returns void.Any ideas?
P.S. I know that init method must return id,I’m interested why this works while it shouldn’t.
Listen to Chuck. He’s smart 🙂
I’ll try to add a bit more detail.
One way to think about this is “If both were declared
-(id)inithow would A return its value to B”?It goes something like this. The
return selfstatement would take the pointer to A and put it in an agreed upon location. This location would be defined in the ABI. On a OSX/x86-64 machine, it’s the RAX register (IIRC). Soreturn selfreally says “write the pointer to self into RAX”.Then when B regains control it knows the return value is in RAX and can use it however it likes. Note you didn’t remove the
return selfstatement from A’s implementation, so self was probably still written to RAX where B found it and used it. Or maybe RAX still had a pointer from the NSObjectinitimplementation. You’d have to disassemble it to know for sure.Now let’s say you didn’t keep the
return selfin A’s implementation. Now there’s some random junk in RAX which B is going to try to use like it’s a pointer to an A. This is where the undefined behavior Chuck mentions comes in. If you’re lucky it will just crash.I’m guessing your code above gave some compiler error/warning that you had to suppress?