Is it ok for subclass of a UIViewController to do some initialization in viewDidLoad before calling super?

StackOverflow https://stackoverflow.com/questions/17843941

Question

So, here is the situation. I have a base class SSSAdEnabledTableViewController with a XIB file that has a _contentView inside the main view and and _tableView inside that view. The base class is being used to render/hide ads.

I then have numerous subclasses that inherit from that base class. Most work fine with regard to the table view except for those that need a non-standard table cell (in this case, SSSDataEntryTableCell).

If I try to register the nib for that custom table cell in my subclass's viewDidLoad after calling super, it does not work and my table view data source and delegate are returning nil cells. However, if I register the NIB before calling super, it seems to work just fine.

The question I have is if this is bad practice and is indicative that I am doing something wrong that in turn is causing the need to do this.

The relevant code snippets are below:

Base Class -- SSSAdEnabledTableViewController

@interface SSSAdEnabledEditTableViewController : UIViewController <ADBannerViewDelegate, UITableViewDataSource, UITableViewDelegate>
{
    // the data table
    UITableView *_tableView;

    // our inner view (to show/hide ads)
    UIView *_contentView;

    // our ad banner
    ADBannerView *_bannerView ;
}

@property (retain, nonatomic) IBOutlet UIView *contentView;
@property (retain, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic, retain) ADBannerView *bannerView ;

@end

And it's viewDidLoad method:

- (void)viewDidLoad
{
    [super viewDidLoad];

    //
    // set the appropriate background color
    //
    UIColor *clr = nil ;

    if ( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad )
    {
        clr = kSSSDefaultBackgroundColor ;
    }
    else
    {
        clr = [UIColor groupTableViewBackgroundColor] ;
    }

    [[self view] setBackgroundColor:clr] ;

    [_tableView setAutoresizesSubviews:YES] ;    
}

Here is one of the subclasses's viewDidLoad method:

- (void)viewDidLoad
{
    // Load the NIB file for our custom cell -- do this before [super viewDidLoad]!
    UINib *nib = [UINib nibWithNibName:kSSSDataEntryTableCell bundle:nil] ;

    // Register the NIB which contains the cell
    [_tableView registerNib:nib forCellReuseIdentifier:kSSSDataEntryTableCell] ;

    [super viewDidLoad];

    // ... does some other stuff not relevant to the question at hand ...
}

So, if I call [super viewDidLoad] first, it appears the code is calling the UITableView methods for cellForRowAtIndexPath BEFORE the NIB is registered and is failing. With it before the call, it appears to work just fine.

Is this the correct way to do this or I am I doing it wrong?

Thanks!

Was it helpful?

Solution

You can call [super viewDidLoad] after performing your own initialization code. That's perfectly reasonable if your superclass expects you to initialize something that it will then use.

You probably should not be calling [_tableView setAutoresizesSubviews:YES]. The table view has a complicated system for laying out its subviews and you don't know if it wants that flag set.

If [self view] is in fact the table view, then I believe the call to [[self view] setBackgroundColor:] is calling tableView:cellForRowAtIndexPath: (indirectly). You can check this by putting a breakpoint in your tableView:cellForRowAtIndexPath: and looking for setBackgroundColor: (and viewDidLoad) in the stack trace.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top