Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically Loading XIB for UITableViewController

Ran into something interesting, want to know if I'm doing something wrong or if this is the correct behavior.

I have a custom UITableViewController. I ASSUMED (first mistake) that if you initialize as such:

[[CustomTableController alloc] init];

it would automatically load from a XIB of the same name, CustomTableController.xib, if it is in the same directory and such.

HOWEVER

This does not work; doesn't load the XIB. BUT, if I change the parent class of my controller from 'UITableViewController' to 'UIViewController', EVERYHTING WORKS FINE!

Calling:

[[CustomTableController alloc] init];

loads the controller and view from my xib.

Am I doing something wrong? Is this a bug? Expected behavior?

like image 228
ACBurk Avatar asked Apr 07 '10 22:04

ACBurk


1 Answers

Most of the classes in Cocoa Touch list a "designated initializer" that you're supposed to call from your init methods when you subclass them. When you create your own custom class, it's a good idea to check the documentation to find the designated initializer for your superclass. When you initialize the class using some other initializer from a more general superclass (which you're doing by calling - [NSObject init] in this case), you rob your direct superclass of its opportunity to properly initialize its state. Sometimes you can get away with this. Often you can't.

UIViewController's documentation states that its designated initializer is -initWithNibName:bundle:. If you call this method with a nil nibName, it will look for a nib that matches your class name. The behavior of -init is undocumented for UIViewController. Based on the behavior you're seeing, it seems like it may be calling [self initWithNibName:nil bundle:nil], but it would be safer to call initWithNibName:bundle: directly rather than relying on this undocumented behavior.

UITableViewController only defines a single initializer, -initWithStyle: (although it doesn't specify this method as the designated initializer). This method initializes your UITableViewController without using a nib, which is usually fine. Since you don't add subviews to a UITableView, there usually isn't much to be gained by configuring your UITableViewController via a nib.

If decide you want to configure your UITableViewController via a nib anyway, the documentation tells us that we can safely bypass -initWithStyle: and call UIViewController's initWithNibName:bundle: method. Here is what the documentation tells us about how our UITableView and its controller will be initialized in each case:

  • If a nib file is specified via the initWithNibName:bundle: method (which is declared by the superclass UIViewController), UITableViewController loads the table view archived in the nib file. Otherwise, it creates an unconfigured UITableView object with the correct dimensions and autoresize mask. You can access this view through the tableView property.

  • If a nib file containing the table view is loaded, the data source and delegate become those objects defined in the nib file (if any). If no nib file is specified or if the nib file defines no data source or delegate, UITableViewController sets the data source and the delegate of the table view to self.

In summary, the documentation for most Cocoa Touch classes either specify a single designated initializer or a handful of initializers that you can call safely from your subclasses. Always refer to the documentation for your superclass to figure out which initializer your subclass should call.

like image 90
cduhn Avatar answered Oct 20 '22 21:10

cduhn