TransWikia.com

Initializing Objective-C property in child class

Stack Overflow Asked on February 1, 2021

Apple recommends that you access the instance variables that back your properties directly, rather than using a getter/setter, when initializing a class:

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html

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;
}

2 Answers

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.

Answered by LightMan on February 1, 2021

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).

Answered by Sebastian on February 1, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP