I'm just curious about this question, I find this solution absolutely wrong, so I'm not using it, but since it happened to me erroneously (a typo that costed me hours of debugging) now I'm posting the question here to find an answer to why this all happened.
I have three classes:
the SharedObject class, which is a dumb class that does nothing...or well, does stuff:
// .h file
@interface SharedObject : NSObject
- (void) doStuff;
@end
// .m file
#import "SharedObject.h"
@implementation SharedObject
- (void) doStuff{
NSLog(@"doin' stuff");
}
@end
the Superclass class which declares an ivar of SharedObject class, along with two methods, one just should (but doesn't) init the object, the other uses the object:
// .h file
#import "SharedObject.h"
@interface Superclass : NSObject{
SharedObject *_sharedObj;
}
- (void) initSharedObject;
- (void) useSharedObject;
@end
// .m file
#import "Superclass.h"
@implementation Superclass
- (void) initSharedObject{
;;
}
- (void) useSharedObject{
[_sharedObj doStuff];
}
@end
the Subclass class, subclass of Superclass (sorry for the naming mess!) which actually implements the initSharedObject
method and inits sharedObject; This subclass however has an hidden category (here's the mess where no compile error is given) where the SharedObject ivar is overridden with the exact same name:
// .h file
#import "Superclass.h"
@interface Subclass : Superclass{
}
@end
// .m file
#import "Subclass.h"
@interface Subclass (){
//here's where the mess takes place
SharedObject *_sharedObj;
}
@end
@implementation Subclass
- (void) initSharedObject{
[super initSharedObject];
//this class inits the shared object here.
_sharedObj = [SharedObject new];
}
@end
Now, despite I'm aware of the fact that what's written up here is just wrong, I was asking myself why I'm getting this weird behaviour; If instantiate a Subclass and call initSharedObject
and useSharedObject
on it like this:
Subclass *test = [Subclass new];
[test initSharedObject];
[test useSharedObject];
nothing happens, and by nothing I mean absolutely nothing, no compile errors/warnings of course, but neither execution errors, the method call gets ignored and anything goes by; If I move the useSharedObject
method implementation inside Subclass I have the correct log in console.
I'm wondering what happens exactly, at runtime, when I erroneously override that Ivar. Any guess I had feels smelly so I'd like to know if somebody has a precise and correct answer on how the compilation works in that scenario and why the log isn't called.
The lack of compiler diagnostic is a bug. The compiler should be able to see the duplicate ivars and complain. You should file a bug report at http://bugreport.apple.com.
The behavior at runtime is correct. An instance of Subclass
has two distinct ivars, even though they have the same name. -[Subclass initSharedObject]
initializes the ivar declared in Subclass
. Then -[Superclass useSharedObject]
uses the ivar declared in Superclass
. That ivar is nil
so the call quietly does nothing.