11

I am very new to iPhone programming and am running into a little bit of weirdness. For the following class, the init method just never gets called -- I have an NSLog function which should tell me when init is executed. Here's the relevant code:

@interface MyViewController : UIViewController {
}
@end

@implementation MyViewController
- (id) init
{
    NSLog(@"init invoked");
    return self;
}
@end

Any ideas as to what I am doing wrong -- if anything? Hopefully I provided enough information.

Thanks.

Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
farhany
  • 1,243
  • 2
  • 17
  • 29

5 Answers5

28

If you are using a Storyboard, initWithCoder: will be called. Reference document says:

If your app uses a storyboard to define a view controller and its associated views, your app never initializes objects of that class directly. Instead, view controllers are either instantiated by the storyboard—either automatically by iOS when a segue is triggered or programmatically when your app calls the storyboard object’s instantiateViewControllerWithIdentifier: method. When instantiating a view controller from a storyboard, iOS initializes the new view controller by calling its initWithCoder: method instead. iOS automatically sets the nibName property to a nib file stored inside the storyboard.

The initWithCoder: method isn't part of the default template of a .m file, so you have to add yourself in your UIViewController subclass:

- (id)initWithCoder:(NSCoder *)aDecoder {

    self = [super initWithCoder:aDecoder];

    if (self) {
        // Custom initialization
        NSLog(@"Was called...");
    }

    return self;
}

There is no need to delete initWithNibName:bundle: from your code, but it won't be called anyway.

reinaldoluckman
  • 6,317
  • 8
  • 42
  • 50
  • could you elaborate on this? Im using a viewController of subclass MyController which I have set the viewcontroller I made in storyboard to. However, in my .m file, I only see a initWithNibName method and no initWithCoder method. Am i supposed to delete initWithNibName and put in initWithCoder or am I doing something else wrong? – snapfish Mar 02 '14 at 00:47
  • There is no need to delete initWithNibName. Just add the initWithCoder (this method isn't in the default template for a .m file). I've changed my answer to denote this. – reinaldoluckman Mar 03 '14 at 12:29
  • 1
    Thanks for accepting my edit, no idea why it was rejected or what they think self is going to be without the [super init] Grrr. Cheers :) – B_o_b May 03 '14 at 10:06
  • I don't know why too. Thanks for pointing that. I really forgot. :) – reinaldoluckman May 04 '14 at 03:34
23

You are probably creating your view controller from a NIB file. So, instead of calling "init" message, this is the one creator message being called:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}

Try if that is the one being called. What Sean said is true. You could use those messages to accomplish similar things.

Good luck.

Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
  • Right after I posted my comment above, I realized why init wasn't being called... :P – farhany Apr 21 '09 at 23:19
  • The designated initializer. Override if you create the controller **programmatically** and want to perform customization that is not appropriate for viewDidLoad. –  Apr 21 '11 at 10:46
3

Is the view coming up? Use these methods for additional initialization:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    //...
}

// Implement viewDidLoad to do additional setup after loading the view.
- (void)viewDidLoad {   
    [super viewDidLoad];
    //..
}
Sean
  • 2,453
  • 6
  • 41
  • 53
  • Thanks! That worked. Though it leaves a little sour taste in my mouth to see some inconsistencies in Obj-C on iPhone. Oh well. – farhany Apr 21 '09 at 11:53
2

Refer 'designated initializer' in reference document too.

eonil
  • 83,476
  • 81
  • 317
  • 516
2

But, a UI component has sometimes severals init* methods, do we need to override all these methods in order to do some init. stuff?

eBuildy
  • 99
  • 1
  • 3
  • 1
    Seems like you only have to override the "designated initializer". The only way to find out which init* method this is is via the documentation. – Nestor Apr 07 '11 at 04:37