Search code examples
iosobjective-coopinheritancesuperclass

How to pass value from subclass to super class during initialization


Suppose, I've two view controller. ViewController1 is the sub class of ViewController2. From subclass (ViewController1), I called superclass init method & passed a value by parameter & assigned that value to the superclass variable. But In superclass (ViewController2)'s viewDidLoad method, that value is always null. Why ? How can I pass that value from sub to super so that I can get that value in super class's viewDidLoad method ?

ViewController1.h

@interface ViewController : ViewController2

@end

ViewController1.m

@implementation ViewController

- (instancetype)init
{
    self = [super initWithName:@"Hello"];
    if (self) {
        NSLog(@"1  :");
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.


}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

ViewController2.h

@interface ViewController2 : UIViewController

@property (nonatomic, strong) NSString *name;
-(instancetype)initWithName:(NSString *)name;

@end

ViewController2.m

- (instancetype)initWithName:(NSString *)name
{
    self = [super init];

    if (self) {
        self.name = name;
    }

    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    NSLog(@"2  : %@", self.name);

}

@end

Solution

  • I tired your code and it worked just fine. I suspect, that you don't instantiate your ViewController directly. Do you use storyboard in your project? If yes - you should override initWithCoder: in ViewController.

    However, it is bad idea to set any properties of view controllers during init-family methods. According to Apple recommendations, all customisation should be done in -viewDidLoad or -viewWill/DidAppear methods.

    If you absolutely in need to set name property from outside, it is better you assign it directly, not trough passing argument to init method.

    One more thing - initWithNibName:bundle: is Designated initializer. It means, that your subclasses absolutely must in the end call it during initialisation chain.