Jason R. Anderson

Software Engineer & UX Designer

You keep using this word, #define. It does not mean what you think it means.

Hello there, fellow Objective-C developers. I’ve had to review a lot of code the past six months or so and there’s something I’ve been seeing far too often. Overuse — dare I say misuse? — of the C preprocessor. I can understand some legacy hangups for C devs coming to Objective-C, but let’s face it…there aren’t that many C devs left in the wild these days. At least not in their 20’s like the candidates submitting their code samples my way. Even if you are a C dev used to doing things a particular way, why use the C preprocessor for things the language can already do…better? I’m talking about using #define in place of constants and enums.

I can’t tell you how many projects I’ve reviewed in the past months with headers stuffed with things like the following:

#define kMyAppRefreshInterval 100.0
#define kMyAppRepeatCount 3
#define kMyAppBaseURL @"http://myapp.com/"

#define MyAppStatusAvailable 0
#define MyAppStatusBusy 1
#define MyAppStatusUnavailable 3
#define MyAppStatusOffline 4

So what’s wrong with that? Well, for starters…unless these values need to be accessed by other portions of the app, do yourself a favor and keep them out of the damn header — sorry…that’s a post for another time. More to the point of this post, using the preprocessor to handle your variable assignment kills the features of your IDE, like code completion, debugging, and warning/error flags.

Well, What Do You Suggest?

The Objective-C language already provides ways to do what you’re attempting with your #define statements. Observe.

static const NSTimeInterval kMyAppRefreshInterval = 100;
static const NSUInteger kMyAppRepeatCount = 3;
static NSString *const kMyAppBaseURL = @"http://myapp.com/";

//if you need that string constant available externally add the following to the .h file
extern NSString *const kMyAppBaseURL;
//and then this in the .m file
NSString *const kMyAppBaseURL = @"http://myapp.com/";

typedef NS_ENUM(NSUInteger, kMyAppStatus) {
	MyAppStatusAvailable,
	MyAppStatusBusy,
	MyAppStatusUnavailable,
	MyAppStatusOffline
}

Try accessing any of those constants elsewhere in your app, and lo and behold the IDE recognizes your variables! It finishes your thoughts for you, and barks at you if you try to change the value of your constant after it’s defined. Anyway, give it a try. You’ll feel better, and the next person to inherit your code will thank you for it.