1.
An #if directive is used to test an arithmetic expression. As shown in Listing 5-3, it is paired with an#endif directive, which together enclose conditional text. The arithmetic expression is of integer type and may contain the following elements:
- Integer and character constants.
- Arithmetic operators, bitwise operations, shifts, comparisons, and logical operations (as defined in Appendix A).
- Preprocessor macros. The macros are expanded before computation of the expression.
- Uses of the defined operator, which is used to check whether a macro is defined.
- Identifiers that are not macros, which are all assigned the value zero when being evaluated.
The #line directive is used to supply a line number for compiler messages. If an error happens during the compiling process, the compiler shows an error message with references to the name of the file where the error happened and a corresponding line number, thereby making it easier to find the code that generated the error. The syntax for the #line directive is
#line LineNumber "FileName"
LineNumber is the new line number that will be assigned to the next code line. The line numbers of successive lines will be increased one by one from this point on. The “FileName” (surrounded in double-quotes) is an optional parameter that enables you to redefine the file name that will be displayed. Xcode and the Objective-C compiler use of the #line directive are illustrated in the following code fragment:
...
#line 10 "Elements.m"
int ?numProtons;
This code will generate an error that will be shown as error in file "Elements.m" at line 11.
The Xcode IDE displays the line numbers of source files and automatically displays errors and warnings while you enter code and at compilation; hence, you rarely have need to use this directive in your source files.
The pragma directive (#pragma) is used to specify additional options to the compiler, beyond that conveyed by the Objective-C language itself. These options are specific for the platform and the compiler being used. The syntax for the #pragma directive is
#pragma PragmaOptions(s)
The pragma options are a series of characters that correspond to a specific compiler instruction (and arguments, if any), and cause an implementation-defined action. If the compiler does not support a specific argument for a #pragma directive, it is ignored and no error is generated.
The Apple Objective-C compiler supports numerous pragma options; the exact options available can be found in the reference documentation for the compiler.
Xcode includes support for several #pragma mark directives. You would use these directives in implementation source files to categorize methods when viewing them within the IDE. Let’s look at an example to see how this works. The Xcode workspace window contains a jump bar at the top of the editor area; it is used to hierarchically view items in the workspace. If you click an item in the jump bar, it displays items at the same level within the hierarchy (as shown in Figure 5-3).
Figure 5-3. Using the Xcode jump bar to display methods
Figure 5-3 shows that clicking a class implementation in the Xcode jump bar brings up a pop-up window that displays a list of the Hydrogen class implementation’s methods. Now this is where pragma mark directives enter the picture—they can be used to organize how these methods are displayed in the jump bar pop-up. You can create a divider visible in the jump bar pop-up using the directive
#pragma mark -
You create a label used to categorize one or more methods using the directive
#pragma mark MarkName
MarkName is the label for the methods that will be displayed in the pop-up.
The following example includes pragma mark directives for the Hydrogen class implementation created in Chapters 2 and 3. These updates (shown in bold in Listing 5-8) categorize the class custom initialization methods.
Listing 5-8. Example #pragma mark Directive Usage
#pragma mark -
#pragma mark Custom Initializers
- (id) initWithNeutrons:(NSUInteger)neutrons
{
if ((self = [super init]))
{
// Initialization code here.
_chemicalElement = @"Hydrogen";
_atomicSymbol = @"H";
_protons = 1;
_neutrons = neutrons;
// Create helper for message forwarding
helper = [[HydrogenHelper alloc] init];
}
return self;
}
#pragma mark -
If you now click the Hydrogen implementation in the Xcode jump bar (as shown in Figure 5-4), the pop-up display lists the method initWithNeutrons:, prefaced with a label of Custom Initializers, and surrounded by dividers.
Figure 5-4. Using the #pragma mark directives
Particularly for large projects and classes that contain a large number of methods, #pragma markdirectives provide a mechanism that facilitates the categorization and organization of class methods and make the jump bar more efficient to use.
4.
Function-like macro definitions accept two special operators (# and ##) in the replacement sequence. The stringification operator (represented by the # symbol) is used to replace a macro input parameter with the corresponding text string (surrounded by double-quotes). The concatenation operator (represented by the ## symbol) is used to concatenate two tokens, leaving no blank space between them.
#define xstr(s) str(s) #define str(s) #s #define foo 4 str (foo) ==> "foo" xstr (foo) ==> xstr (4) ==> str (4) ==> "4"