Learn Objective-C: Conditional Compilation
Building off of last week’s post, there are a few more preprocessor directives that allow you to control which portions of a program are compiled.
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 The #ifdef, #endif, and #else directives work just like the The #ifdef, #endif, #elseif…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
is sufficient to pass the #ifdef test; no value actually has to be specified for the constant.
So how does it work?
# define DATADIR ~/Documents
NSLog(@"Not running in OS X");
This can also be used for debugging:
NSLog(@"Data array is %@", self.dataArray);
This makes the code (your debugging intentions) clearer. When the program is working properly, you can undefine DEBUG and the NSLogs 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)
The example is rather self explanatory.
The operator defined (something) can also be used in #if statements:
// Is equivalent to
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:
Subsequent #ifdef DEBUG and #if defined(DEBUG) statements evaluate to false.
Conditional compilation can be useful in determining if you’re running on an iPad or not. Apple provides a UIUSERINTERFACE_IDIOM() macro that can perform the check for you:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
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 20MBs can be downloaded off a 3G 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.
Author: Feifan Zhou