Scrungepipes
Scrungepipes

Reputation: 37581

Why do AppDelegates have an instance variable for the root controller?

This example is taken from The Big Nerd Range iPhone book (page 143/144) - ItemsViewController is a subclass of UITableViewController:

@interface HomepwnerAppDelegate : NSObject <UIApplicationDelegate>
{
    UIWindow *window;
    ITemsViewController* itemsViewController;
}

....
itemsViewController = [[ItemsViewController alloc] init];
[window setRootViewController: itemsViewController]

My question is why is it necessary to have the iVar itemsViewController, why not just do this instead:

...
window.rootViewController = [[ItemsViewController alloc] init];

I presume the window will destroy its rootViewController when the app exits and thus there's no leaks, and the window will be in existence for the lifetime of the app so I don't understand why this and many other example have a separate iVar for the root controller?

TIA

Upvotes: 0

Views: 133

Answers (4)

Sonny Saluja
Sonny Saluja

Reputation: 7287

This is totally stylistic choice. There are other ways to get the convenience accessor. I don't ever create an ivar in my rootViewController never changes. I will usually go for a read only property.

@property (nonatomic, readonly) MyRootViewController *rootViewController;

- (MyRootViewController *)rootViewController {
    if ([self.window.rootViewController isKindOfClass:[MyRootViewController class]) {
        return (MyRootViewController *)self.window.rootViewController;
    }
    return nil;
}

Upvotes: 0

Nick Lockwood
Nick Lockwood

Reputation: 41005

The reason is historical, I think. Back when that book was written, the window and root view controller both used to be IBOutlets and were set from a nib file called MainWindow.nib.

Also, UIWindow didn't used to have a rootViewController property to assign the control to (the root view controller.view was just added directly as a subview to window), so if you didn't store it in an ivar then it wouldn't be retained by anything and your app wouldn't work because the root view controller would be released as soon as it was created.

These days however, since iOS4 and now ARC, the base project template has been updated and doesn't even have ivars any more (which are no longer needed). It does still have an @property for the view controller, but it's technically not needed any more either, and your alternative solution of assigning a new controller directly to the window.rootViewCOntroller would work fine.

Upvotes: 0

DarkDust
DarkDust

Reputation: 92384

The biggest advantage is simply that you can access the methods of your view controller without needing to cast over and over again:

[itemsViewController doSomething];
// vs.
[(ItemsViewController *)window.rootViewController doSomething];

Depending on the app you might need to refer to the root view controller frequently from the app delegate, for example when implementing the handlers for entering background/foreground and similar app delegate callbacks.

Upvotes: 1

Sonny Saluja
Sonny Saluja

Reputation: 7287

There is absolutely no need to keep the ivar around if you don't need it.

BTW, you will leak ItemsViewController if you don't autorelease it. (Unless you are using ARC)

Upvotes: 0

Related Questions