Online Book Reader

Home Category

Objective-C Programming_ The Big Nerd Ranch Guide - Aaron Hillegass [49]

By Root 506 0
/Developer/SDKs/MacOSX10.7.sdk/usr/include/math.h.) Here are two examples of #import directives:

// Include the headers I wrote for Pet Store operations

#import "PetStore.h"

// Include the headers for the OpenLDAP libraries

#import

In a project, it used to be pretty common to include a collection of headers in every file of code. This led to clutter at the beginning of your file and made compiles take longer. To make life easier and compiles faster, most Xcode projects have a file that lists headers to be precompiled and included in every file. In your Constants project, this file is called Constants-Prefix.pch.

So, how did a constant from math.h get included when main.m was compiled? Your main.m file has the following line:

#import

The file Foundation.h has this line:

#include

The file CoreFoundation.h has this line:

#include

#define


#define tells the preprocessor, “Whenever you encounter A, replace it with B before the compiler sees it.” Look at the line from math.h again:

#define M_PI 3.14159265358979323846264338327950288

In the #define directive, you just separate the two parts (the token and its replacement) with whitespace.

#define can actually be used to make something like a function. In main.m, print the larger of two numbers:

#import

int main (int argc, const char * argv[])

{

@autoreleasepool {

NSLog(@"\u03c0 is %f", M_PI);

NSLog(@"%d is larger", MAX(10, 12));

}

return 0;

}

MAX is not a function; it is a #define. The most basic C version of MAX is:

#define MAX(A,B) ((A) > (B) ? (A) : (B))

So, by the time the compiler saw the line you just added, it looked like this:

NSLog(@"%d is larger", ((10) > (12) ? (10) : (12)));

When you use #define to do function-like stuff instead of simply substituting a value,you are creating a macro.

Global variables


Instead of using #define, Objective-C programmers commonly use global variables to hold constant values.

Let’s add to your program to explain. First, there is a class named NSLocale that stores information about different geographical locations. You can get an instance of the user’s current locale and then ask it questions. For instance, if you wanted to know what the currency is in the user’s locale, you could ask for it like this:

#import

int main (int argc, const char * argv[])

{

@autoreleasepool {

NSLog(@"\u03c0 is %f", M_PI);

NSLog(@"%d is larger", MAX(10, 12));

NSLocale *here = [NSLocale currentLocale];

NSString *currency = [here objectForKey:@"currency"];

NSLog(@"Money is %@", currency);

}

return 0;

}

Build and run it. Depending on where you are, you should see something like

Money is USD

If, however, you mistype the key as @"Kuruncy", you won’t get anything back. To prevent this problem, the Foundation framework defines a global variable called NSLocaleCurrencyCode. It isn’t easier to type, but if you do mistype it, the compiler will complain. Also, code completion in Xcode works properly for a global variable, but not for the string @"currency". Change your code to use the constant:

#import

int main (int argc, const char * argv[])

{

@autoreleasepool {

NSLog(@"\u03c0 is %f", M_PI);

NSLog(@"%d is larger", MAX(10, 12));

NSLocale *here = [NSLocale currentLocale];

NSString *currency = [here objectForKey:NSLocaleCurrencyCode];

NSLog(@"Money is %@", currency);

}

return 0;

}

When the class NSLocale was written, this global variable appeared in two places. In NSLocale.h, the variable was declared something like this:

extern NSString const *NSLocaleCurrencyCode;

The const means that this pointer will not change for the entire life of the program. The extern means “I promise this exists, but it will be defined in some other file.” And sure enough, in the file NSLocale.m, there is a line like this:

NSString const *NSLocaleCurrencyCode = @"currency";

enum

Often you will

Return Main Page Previous Page Next Page

®Online Book Reader