Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIViewController ( init and initWithNibName )

Tags:

Wish to know more about the practical differences between init and initWithNibName. SO answers such as this suggests that it is better to call "initWithNibName" indirectly through "init".

  1. Are there any circumstances that we need to define "init" and "initWithNibName" differently ?
  2. Is it possible that any Nib file needs to be loaded more than once during a single program execution ?
  3. Are questions 1 & 2 inter-related ?
like image 315
Stanley Avatar asked Jan 30 '12 04:01

Stanley


2 Answers

It is not better to call initWithNibName: indirectly through init. You just want to call initWithNibName: at some point. You can do that externally or internally. Some people think it's better to do it internally. I actually have a class called "LayoutUtil" that I keep layout-related helper methods to avoid writing tedious piece of layout-related code over and over. Here is my code to load a UIViewController:

+ (id)loadController:(Class)classType {     NSString *className = NSStringFromClass(classType);     UIViewController *controller = [[classType alloc] initWithNibName:className bundle:nil];     return controller; } 

And then I can just do:

MyViewController *c = [LayoutUtil loadController:[MyViewController class]]; 

If you want, you could add a method called ughhhh to a class and call it in there, it doesn't matter at all. The point is that it is not a better practice to call initWithNibName in the init method though, you just want to make sure you call it at some point when initiating a UIViewController.

- (id)ughhhh {    self = [super initWithNibName:@"Myview" bundle:nil];    if (self != nil)    {    }    return self; } 

A nib file can definitely need to be loaded more than once. Everytime you call initWithNibName on a UIViewController the xib has to be loaded. A lot of people load UIViews that are not owned by a UIViewController like this:

[[NSBundle mainBundle] loadNibNamed:@"nameOfXIBFile" owner:self options:nil]; 

Everytime you call this function you will be loading the nib.

There are certain cases where a nib can be cached. An example would be a UITableView -- but the table view implements it's own cache. The operating system isn't doing any caching automatically.

init and initWithNibName: are related in that initWithNibName: automatically calls init on an object.

like image 166
Michael Frederick Avatar answered Dec 12 '22 02:12

Michael Frederick


It's not ‘better to call "initWithNibName" indirectly through "init"’. You should use whichever one suits your needs better. Saying [[UIViewController alloc] init] is exactly like saying [[UIViewController alloc] initWithNibName:nil bundle:nil], so if those are the arguments you want to pass, you might as well use [[UIViewController alloc] init].

In answer to your questions:

  1. You can define init and initWithNibName:bundle: differently if you want to. You can define just one of them. For example, UIImagePickerController only defines init, and if you try sending it initWithNibName:bundle:, it won't work properly. Or you can define some entirely different init... method. For example, UINavigationController only defines initWithRootViewController:. Whatever init methods you do define must eventually call one of its superclass's init methods.

  2. Yes, a nib can be loaded multiple times. If you create multiple instances of the same view controller subclass, it's likely that you will load the same nib multiple times. In fact, it's possible for a single instance of a view controller to load its nib multiple times. How? If a view controller's view is not currently on screen, and the system runs low on memory, the system will ask the view controller to release its view. If the view controller later needs to put its view back on the screen, it will load the nib again.

  3. Questions 1 and 2 are not related.

like image 37
rob mayoff Avatar answered Dec 12 '22 02:12

rob mayoff