In C/C++, we use directives to include any other header files that our application will need to access. This is done by using the #include
directive. In Objective-C, we use the #import
directive. If you examine the contents of the ViewController.h
file, you will notice that at the top of the file is a #import
statement.
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
{
IBOutlet UILabel *lblFirstname;
IBOutlet UITextField *txtFirstname;
IBOutlet UILabel *lblSurname;
IBOutlet UITextField *txtSurname;
IBOutlet UILabel *lblOutput;
IBOutlet UIButton *btnTapHere;
}
The #import
statement is known as a preprocessor directive. As mentioned previously, in C/C++, you would use the #include
preprocessor directive to include a file's content within the current source file. In Objective-C, you would use the #import
directive statement to achieve the same result, with the exception that the compiler ensures that the file is only included once.
To import a header file from one of the Xcode framework libraries, you would specify the header filename using the angle brackets (<>
) within the #import
statement.
If you wanted to import one of your own custom-built header files containing your own methods, you would specify and make use of the double-quoted marks (""
), as you can see from the following sample code:
#import <UIKit/UIKit.h> #import "MyClass.h" @interface ViewController : UIViewController { }
In this recipe, we will be taking a look at another approach where we can use directives to conditionally compile code based on a conditionally set pre-compiler flag that you can define yourself. This makes it easy for you to selectively enable parts of your application without making your code look messy.
In HelloWorld-Prefix.pch
, we will start by declaring a few macros (so you don't have to litter your code with #ifdef/#endif
blocks). The HelloWorld-Prefix.pch
file is global in scope, so any functions you define there will be available in all of your classes, so this can be very useful.
Declaring compiler directives for your application is a very simple process, and can be achieved by performing the following simple steps:
HelloWorld-Prefix.pch
implementation file from the project navigator, located under the supporting files group.// // Prefix header for all source files of the 'HelloWorld' target in the 'HelloWorld' project // #import <Availability.h> #ifndef __IPHONE_4_0 #warning "This project uses features only available in iOS SDK 4.0 and later." #endif #ifdef __OBJC__ #import <UIKit/UIKit.h> #import <Foundation/Foundation.h> #endif #ifdef DISPLAY_FIRSTNAME #warning "This application will display the value of the First namefield." #else #warning "This application will display the values of both the First name and Surname fields." #endif
btnTapHere
method to be surrounded by an #ifdef
statement, within our ViewController.m
implementation file, as follows:- (IBAction)btnTapHere:(id)sender { #ifdef DISPLAY_FIRSTNAME NSLog(@"Using the Firstname field."); NSString *greeting = [NSString stringWithFormat:@"Welcome to Xcode 4 Cookbook series %@",txtFirstname.text]; #else NSLog(@"Using Firstname and Surname fields."); NSString *greeting = [NSString stringWithFormat:@"Welcome to Xcode 4 Cookbook series %@ %@",txtFirstname.text, txtSurname.text]; #endif lblOutput.text = greeting; lblOutput.font = [UIFont boldSystemFontOfSize:21]; lblOutput.textColor = [UIColorblueColor]; }
Whenever you want to display just the first name of the user, you simply set this to YES
by defining the conditional flag.
Whenever compiler directives are used in Objective-C, they are responsible for responding to and executing the associated snippets of code encapsulated within the #ifdef
and #endif
tags.
This is particularly handy if you only want to force a set of NSLog
messages or values to be used during testing, and not appear during the final release of your application. Some other uses where these types can be used would be, if you were creating a game and you wanted to disable some features in the trial or lite version of your game.
In order to have your application use this compiler directive, we need to add this preprocessing flag to the Preprocessor Macros section, as follows:
DISPLAY_FIRSTNAME=YES
preprocessor flag.That's all there is to it, easy. If you want to turn DISPLAY_FIRSTNAME
off (for example, when you're ready to do your final release build), simply head back to this section and remove the flag from your project preferences.