1

I use to create my views programmatically and have started to switch using XIB files. I found this code:

-(id)init
{
    self = [super initWithNibName:@"HelpViewController"  bundle:nil];
    if (self != nil) {
        // further initialization needed
    }

    return self;
}

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    NSAssert(NO, @"Initialize with -init");
    return nil;
}

It works but why? If I follow the logic, the initWithNibName returns nil and sets it to self. So, self is now nil and then you return self at the end of init. Well, that means you return self which is nil. Is that right?

Also, if I wanted to initialize a NSArray, where should I put it in that init function?

Thanks for the explanation.

Yko

oky_sabeni
  • 7,672
  • 15
  • 65
  • 89
  • In your snippet, if you call `initWithNibName:bundle:`, nothing gets initialized. You should call `init` instead and further initialize the object in it. This *pattern* tries to [enforce proper encapsulation](http://oleb.net/blog/2012/01/initWithNibName-bundle-breaks-encapsulation/) and hide the nib name from the caller because it is an implementation detail. – albertamg Oct 15 '12 at 19:06
  • I'm assuming this is automatically generated code? If so, its basically telling you to call init to initialize it and it will handle the initWithNibName:bundle: on its own inside the init function. Its basically just making things easier for you by having you type less. – RileyE Oct 15 '12 at 19:18
  • No. It's nice auto generated code. It's actually code I found at SO and the point is to encapsulate so I can call [ClassName alloc] init] and not specify the actual Nib name outside of the class. That makes sense. Following the code doesn't. I found one that makes more sense to be honest with initWithNibName returning [self init] instead of nil. I just don't understand that nil. – oky_sabeni Oct 15 '12 at 19:33

3 Answers3

3

Because the init method calls the self = [super initWithNibName...]. So You must call the init method to create the object. If you use initWithNibName it will fails

For Array you should initialize in init method

-(id)init
{
    self = [super initWithNibName:@"HelpViewController"  bundle:nil];
    if (self != nil) {
        // further initialization needed
        myArray = [[NSMutableArray alloc] init];
    }

    return self;
}
Atif
  • 1,220
  • 11
  • 16
  • This is exactly right. Its calling the function in the super class, which should be UIViewController. That function is not editable (well, you shouldn't be editing it), so just trust that it is doing what you want. (PS - This is just a further comment for the OP) – RileyE Oct 15 '12 at 19:19
  • I'm trying to understand the return nil part. I don't get it. I found another one that makes more sense. In initWithNibName, it returns [self init] instead of nil. Well, actually that makes no sense either because [self init] calls initWithNibName... – oky_sabeni Oct 15 '12 at 19:34
  • I think I'm confusing the super class and the UIViewController class. That's what I would like to understand. – oky_sabeni Oct 15 '12 at 19:34
1

You're looking at two different initWithNibName functions.

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    NSAssert(NO, @"Initialize with -init");
    return nil;
}

The above function is overriding the superclass version of initWithNibName. It raises an assertion informing the caller to use init.

self = [super initWithNibName:@"HelpViewController"  bundle:nil];

The above line is calling the superclass version of initWithNibName, which returns a view controller.

If you wanted to initialize an array, you would initialize it where the "further initialization needed" comment is.

Smith
  • 361
  • 1
  • 10
  • Yea. I think I'm confusing the superclass and the UIVIewController class. That's where I would like to understand. Suppose I alloc and init the view controller, it goes to init, calls the super initWithNibName, but that's not the same initWithNibName that is specified in the implementation file right? Or is it since I override it? Then why does it return nil? That part is confusing – oky_sabeni Oct 15 '12 at 19:36
  • @Yko It is not the same initWithNibName, it is the one implemented in the superclass because you call it on [super](http://stackoverflow.com/questions/3095360/what-exactly-is-super-in-objective-c), not self. – albertamg Oct 15 '12 at 19:53
1

It works because you are calling -initWithNibName:bundle: on super (most likely UIViewController), rather than on self (your subclass of UIViewController). If you were to call initWithNibName:bundle on self, then you would hit the assertion or return nil if you have disabled assertions. The superclass implementation of -initWithNibName:bundle: is not affected by your implementation and therefore continues to behave as it normally would.

birikino
  • 71
  • 4