You must bear in mind that declaring an instance variable in a subclass does not redeclare an existing superclass instance variable with the same name, regardless of the purported redeclaration being in the public interface or a class extension. Even if you use the same name, it is a different instance variable.
You can try this yourself. For example:
@interface Base : NSObject {
@private
int _number;
}
@end
@implementation Base
- (id)init { self = [super init]; if (self) _number = 10; return self; }
- (void)logNumber { printf("base = %d\n", _number); }
@end
@interface Derived : Base
@end
@interface Derived () {
int _number;
}
@end
@implementation Derived
- (id)init { self = [super init]; if (self) _number = 20; return self; }
- (void)logNumberDerived { printf("derived = %d\n", _number); }
@end
int main(void) {
Derived *o = [Derived new];
[o logNumber];
[o logNumberDerived];
return 0;
}
outputs:
base = 10
derived = 20
because _number
in superclass is different from _number
in subclass (extension). If you inspect the symbols in the binary output with nm -a
, you’ll notice that the compiler generates two different symbols:
s _OBJC_IVAR_$_Base._number
s _OBJC_IVAR_$_Derived._number