Learn Objective-C: Conditional Compilation
Building off of the last post, there are a few more preprocessor directives that allow you to control which portions of a program are compiled.
The #ifdef
, #endif
, #else
, and #ifndef
Statements
Sometimes (and hopefully not often), a program relies on system- or platform-specific features that must be written differently across different platforms. For example, not all iOS devices can run iOS 4.x, so any program that uses 4.x features must check to see if the system can support that feature. Or an application for OS X can check for the architecture of the system, PowerPC or Intel, or the version of the OS.
The #ifdef
, #endif
, and #else
directives work just like the if…else
construct; the #endif
directive is used to end an #ifdef
block, just like a curly brace (}
) ends an if block.
Note that a definition such as #define POWER_PC
is sufficient to pass the #ifdef
test; no value actually has to be specified for the constant.
So how does it work?
#ifdef MAC_OS_X
# define DATADIR ~/Documents
#else
NSLog(@"Not running in OS X");
#endif
This can also be used for debugging:
#ifdef DEBUG
NSLog(@"Data array is %@", self.dataArray);
#endif
This makes the code (your debugging intentions) clearer. When the program is working properly, you can undefine DEBUG
and the NSLog
s will not even be compiled in.
The #ifndef
statement is the exact opposite of #ifdef
- the code that follows gets executed only if the value is not defined.
The #if
and #elif
Directives
These directives are similar to if()…
and else if()…
. For example, the following appears in NSString.h
:
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
#define NSMaximumStringLength (INT_MAX - 1)
#endif
The example is rather self explanatory.
The operator defined (something) can also be used in #if
statements:
#if defined(DEBUG)
// Is equivalent to
#ifdef DEBUG
A common use of this is #if
defined (DEBUG
) && DEBUG
, which will be true if DEBUG
has been defined to a non-zero value.
The #undef
Operator
The #undef
operator undefines a name:
#undef DEBUG
Subsequent #ifdef DEBUG
and #if defined(DEBUG)
statements evaluate to false.
Determining iPads
Conditional compilation can be useful in determining if you’re running on an iPad or not. Apple provides a UI_USER_INTERFACE_IDIOM()
macro that can perform the check for you:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
//iPad code
else
//iPhone code
If you have extensive code changes or want to load a different set of resources for example, the iPad code won’t ever get compiled for the iPhone and vice versa, which could simplify the resulting binary (remember, only apps under 100MBs can be downloaded off a cellular connection. You want to make your app as small as reasonably possible).
This post is part of the Learn Objective-C in 24 Days course.
Previous Lesson | Next Lesson |