Tuesday, December 15, 2009

Objective-C Tuesdays: global variables

Last time we finished up our series on looping with a look at common uses for goto. Today we're starting a new series examining variables in Objective-C. Our first topic in the series is global variables.

Any variable declared outside of a function or method, class @interface or struct declaration is a global variable:
int count1; // global

int main(int argc, char *argv[]) {
  int count2; // local to main()
  ...
}
Initialization: By default, global variables are initialized to zero. For regular pointer types (including regular C strings) this means NULL is the default value; for Objective-C object pointers, it's nil by default. (This is different than local variables, which don't have a guaranteed initial value and thus should always be explicitly initialized.)

A global variable can be assigned an initial value when defined, but there's a tricky restriction: the initial value must be something the compiler can calculate at compile time. In general, this means you can only use literal values like numbers, characters and string literals, and you can only use basic numeric operators. Here are some examples of global variables with legal initial values:
int count; // defaults to 0
int daysPerYear = 365;
int secondsPerDay = 24 * 60 * 60;
Unfortunately you can't call functions or methods or use other global variables when assigning initial values. Here are some examples of illegal initial values for global variables:
// WARNING: WON'T COMPILE

// ERROR: function call not allowed
size_t titleLength = strlen("Objective-C Tuesdays");

// ERROR:  method call not allowed
NSUInteger subtitleLength = [@"global variables" length];

// ERROR:  calculation uses other global variables
unsigned long totalLength = titleLength + subtitleLength;
This restriction generally means that global Objective-C object types can't be initialized when they're declared:
// WARNING: WON'T COMPILE
NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", nil];
There is one exception: NSString global variables can be initialized with Objective-C string literals (those special @ strings):
NSString *title = @"Objective-C Tuesdays";
If you need to do some complex initialization on your global variables, your only choice is to do it explicitly when your program starts. There are a few common places to do this sort of work:
  • at the start of main()
  • in your application delegate's -init method
  • in your application delegate's -applicationDidFinishLaunching: method
  • in the +initialize method of one of your classes
If the global variable is closely associated with a particular class, the +initialize method for that class is a good way to keep related code grouped together. Otherwise, -applicationDidFinishLaunching: is commonly used in Cocoa-touch programs while the start of main() is the traditional place in C programs.

Next time, we'll look at accessing global variables from multiple .m and .c files.

No comments: