Reputation: 13
Apple recommends that you access the instance variables that back your properties directly, rather than using a getter/setter, when initializing a class:
However, it seems that instance variables backing a property in a parent class are not accessible in the child class; why is this the case? I'm extending a class in a library (Cocos2d) where not all the instance variables are initialized in the parent class init function. For example:
---
@interface parentClass
@property (assign) int myProperty;
----
@interface childClass : parentClass
----
@implementation childClass
- (id) init {
// this doesn't work.
_myProperty = 0;
}
Upvotes: 1
Views: 1526
Reputation: 3575
You can do the following in your parentClass.h:
@interface parentClass {
@protected
int _myProperty;
}
@property (nonatomic) int myProperty;
Then, in your childClass.m
- (instancetype)init {
if (self=[super init]) {
_myProperty = aValue;
}
}
iVars are declared as protected by default, so your children can see them. There is no need to write @protected. And for your information you can also declare them as @private or @public.
But if you write the protected iVar in a private interface in your parentClass.m, this will not work and the children will not see it.
Upvotes: 0
Reputation: 7720
You can't access instance variables from your superclass in a subclass, so _variableName
will also not work.
You init
method will look something like this
- (instancetype)init {
if (self=[super init]) {
// subclass initialisation goes here
}
}
Once [super init]
returned an object, the superclass part of your object is initialised, so it should be safe to access properties using their getters and setters:
- (instancetype)init {
if (self=[super init]) {
self.superClassProperty = aValue;
}
}
Have a look at "Don't message self in Objective-C init" on QualityCoding on when to use instance variables and when to call methods (e.g. property accessors). In short: Only call methods when your object is in a consistent state.
Why can't you access backing ivars?
A property declaration in a header declares a getter and setter for the property, a backing ivar is created when the property is synthesised, which happens in the implementation. (Automatic and manual synthesis doesn't make a difference). The ivar declaration is therefor only visible in the implementation. If you absolutely have to access ivars in subclasses, you have to make them public (or semi-public by putting them in a header for subclassing only).
Upvotes: 2