Objective-C Lesson 7: Enumerated Types and typedefs

Aside from the built-in data types, such as ints and floats, as well as the types provided by the Foundation and Cocoa classes, such as NSArray, you can create your own types- to an extent.

Enumerated Types

Objective-C allows you to create a type that will only take certain, predefined values. This is particularly useful, as it allows the programmer to model real-world collections, such as the months of the year, or the players in a game with a specific number of players. The syntax is quite simple. To create a Direction type as might be found in a map application, use the following code:

enum direction {north, south, west, east};

You can then use it anywhere else you might have a variable (prefixing it with the enum keyword):

enum direction currentDirection = south;
     // …
     if (currentDirection == north)
          NSLog(@"Player is going north.");
     // …

Note that simply declaring an enumerated type does not result in compiler enforcement—in the previous example, any value could have been assigned to currentDirection and the compiler would not have complained. But this, obviously, defeats the purpose of the enumerated type in the first place.

Note that an enumerated type is simply a specific list of integers, where each value is given one (or more) names. By default, the first element in a list is set equal to 0, and each subsequent element is assigned a value one greater. In the example above, the value north is equivalent (in all contexts) to the integral constant 0, south is equal to 1, and so on. You can also specify an integer value to be equal to an enumerated value:

enum direction {north, south = 5, west = 4, east};

Here, north is equal to 0, south is equal to 5, west is equal to 4, and because no value has been specified for east, it uses the “next” value after the previous declaration—therefore, east is equivalent to 5. This is perfectly acceptable—in one enum, multiple values can share one representative value.

Note also that the defined values do not have to be positive. In Foundation, there is an enumerated type is (partly—the rest is below) defined as:

enum {
   NSOrderedAscending = -1,
   NSOrderedSame,
   NSOrderedDescending
};     //…

The purpose of enumerated types is to create specifically named constants- don’t think of them as integers. Think of them as explicit names for certain values.

The typedef Statement

A typedef allows the programmer to define one Objective-C type as another. For example,typedef int Counter; defines the type Counter to be equivalent to the int type. This drastically improves code readability.

It is also useful if you have some simple code from another language, such as Java:

typedef NSString *String;
     // Java string
     String userInput = //… 

     // Valid Objective-C code because of previous typedef
     // (String userInput) is the same as (NSString *userInput)
     // And will be treated by the compiler as such

To define a new typedef,

  1. Write the statement as if a variable of the original type was being declared

  2. Where you would put the name of the variable (after the type), place the new type name.

  3. Prefix everything with typedef

This is particularly useful with enumerated types. To create a new type called Direction, we could write

typedef enum {north, south, west, east} Direction;
     Direction initialStep = // …

The NSComparisonResult is defined in a similar manner.

enum {
   NSOrderedAscending = -1,
   NSOrderedSame,
   NSOrderedDescending
};
typedef NSInteger NSComparisonResult;

Many comparison methods return NSComparisonResult:

- (NSComparisonResult)compare:(NSString *)string;

You could have a line such as this in your program:

if ([userName compare:savedName] == NSOrderedSame)
     // …Do something

You’re actually testing if the method returned 0… but the typedef and enum made that a lot clearer.

This post is part of the Learn Objective-C in 24 Days course.


Previous Lesson Next Lesson