Thought of the day: get rid of AppDelegate.h

We’ve all seen them (or written them).  App delegates that have their hands in everything, paired with hundreds of code snippets like [[AppDelegate sharedInstance].viewController pushViewController:[AppDelegate sharedInstance].loginViewController]. This kind of high coupling, low cohesion “design” is the enemy of stable, manageable code. Once its there, it is a real pain to get rid of.  So why not spare yourself the effort and make it hard for people to make the wrong choice?  Make the class anonymous!

Now of course, there is really no such thing as anonymous classes in Objective-C, unless you wanted to do something hardcore like modify the class definition at runtime, but there’s an easy thing you can do make it seem anonymous and give rookie developers pause.  Get rid of AppDelegate.h.

As you probably know, headers serve two purposes.  When the compiler sees the main implementation of a class, it uses it to validate that methods are implemented, compile a list of ivars, and trigger property auto-synthesis.  When it sees a method call in other files, it just uses the header to validate that the class exists, that the method exists, and in ARC inject appropriate retain and release messages.  If you move the contents of AppDelegate.h into AppDelegate.m, you satisfy the former while preventing the latter. The only place that is really impacted by this is main.m which has this line:

        return UIApplicationMain(argc, argv, nil,
            NSStringFromClass([AppDelegate class]));

This basically provides compiler level validation that AppDelegate exists and then extracts the string “AppDelegate” from it. This is a little silly since your app will crash instantly otherwise. You can just change it to be:

        return UIApplicationMain(argc, argv, nil, @"AppDelegate");

As a result, all my projects will start with a simple, clean AppDelegate.m file that looks like this:

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder 
@property (strong, nonatomic) UIWindow *window;

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Do stuff here.
    [self.window makeKeyAndVisible];
    return YES;


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s