views:

633

answers:

4

What kind of information is stored behind such an enum type thing? Example:

typedef enum {
    UIViewAnimationCurveEaseInOut,
    UIViewAnimationCurveEaseIn,
    UIViewAnimationCurveEaseOut,
    UIViewAnimationCurveLinear
} UIViewAnimationCurve;

I am not sure if I can safely add such an enum constant to an array. Any idea?

+2  A: 

Enums in Objective-C are the same as enums in vanilla C. It's just an int. If you're using an NSArray, then it expects a pointer and you'll get a warning if you try to add an int to it:

NSMutableArray *myArray = [[NSMutableArray alloc] init];
[myArray addObject:UIViewAnimationCurveEaseInOut];

// Last line results in:
//    warning: passing argument 1 of 'addObject:' makes
//    pointer from integer without a cast
Algorithmic
+5  A: 

Enums are typically int values. You can store them in an array by wrapping them in an NSNumber:

[myMutableArray addObject:[NSNumber numberWithInt:myAnimationCurve]];

... then get them back out like this:

UIViewAnimationCurve myAnimationCurve = [[myMutableArray lastObject] intValue];
iKenndac
+4  A: 

Enums in Objective-C are exactly the same as those in C. Each item in your enum is automatically given an integer value, by default starting with zero.

For the example you provided: UIViewAnimationCurveEaseInOut would be 0; UIViewAnimationCurveEaseIn would be 1, and so on.

You can specify the value for the enum if required:

typedef enum {
    UIViewAnimationCurveEaseInOut,
    UIViewAnimationCurveEaseIn = 0,
    UIViewAnimationCurveEaseOut,
    UIViewAnimationCurveLinear
} UIViewAnimationCurve;

This result of this would be: UIViewAnimationCurveEaseInOut is 0; UIViewAnimationCurveEaseIn is 0; UIViewAnimationCurveEaseOut is 1; and so on. However, for basic purposes you shouldn't need to do anything like that; it just gives you some useful info to toy with.

It should be noted based on the above, that an enum can't assume to be a unique value; different enum identifiers can be equal in value to each other.

Adding an enum item to a NSArray is as simple as adding an integer. The only difference would be that you use the enum identifer instead.

[myArray addObject:[NSNumber numberWithInt:UIViewAnimationCurveEaseInOut]];

You can check this out for yourself by simply outputting each enum to the console and checking the value it provides you with. This gives you the opportunity to investigate the details of how it operates. But for the most part you won't really need to know on a day to day basis.

fatalexception
+2  A: 

If you're storing a large collection of 32-bit integers, consider using the appropriate CF collection type rather than the NS collection type. These allow you to pass in custom retain methods, which gets rid of the need to box every integer added to the collection.

For example, let's say you want a straight array of 32-bit ints. Use:

CFMutableArrayRef arrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);

The last parameter tells the array to not retain/release the "addresses" you pass in to it. So when you do something like this:

CFArrayAppendValue(arrayRef, 1);

What the array thinks is that you're passing in a pointer to an object living at the memory address 0x1. But since you told it to not call retain/release on that pointer, it gets treated as a standard int by the collection.

FWIW, for educational value, standard NSMutableArrays have equivalent CF types. Through toll-free bridging you can use the CF collection as a standard Foundation collection:

CFMutableArrayRef arrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, kCFTypeArrayCallbacks);
NSMutableArray *array = (NSMutableArray *)arrayRef;
[array addObject:@"hi there!"];
NSLog(@"%@", [array objectAtIndex:0]); // prints "hi there!"

You can apply the same tricks to dictionaries (with CFDictionary/CFMutableDictionary), sets (CFSet/CFMutableSet), etc.

iPhone Dev