views:

108

answers:

3

Hi,

I'm new to Objective-C, but experienced in C++ and C.

I want to store some enum constants in an array. In C++ I would do something like this:

enum color {RED, BLUE, YELLOW, GREEN};
vector<color> supportedColors;
supportedColors.push_back(RED);
supportedColors.push_back(GREEN);

But the NSArray will only store object pointers (ids). So how should they be stored? I could possibly cast them to integers and store them in an NSNumber object, but this seems messy.

I wonder what experienced obj-c programmers do?

+6  A: 

Cast them to integers and store them in NSNumbers. :)

Native C types are really second class citizens in the Cocoa collection classes, and are often verbose to work with if you want to intermingle. C says that enums have integral values, so it's safe to use them as ints in this way.

Depending on what you're doing of course, you can simplify the manipulation code by wrapping that enum in an actual object ("MyColor") that has the enum as a property on it. These objects could then be tossed around in the collection classes as desired, with some upfront and runtime overhead that are unlikely to matter from a perf standpoint, depending on what you're doing.

quixoto
Is there a nice Obj-C type for something I can use in a switch...case and also put into an NSArray?
joerick
@joerick: `NSNumber` can be used with `switch` statements: `switch([myNsNumber intValue]) ...`.
Georg Fritzsche
Of course. Thanks, guys!
joerick
joerick: Strictly speaking, NSNumber objects cannot be used with `switch` statements. The way around that, as Georg provided, is to ask the NSNumber object for its value as an `int`, which *can* be used with a `switch` statement, and then so use it.
Peter Hosey
A: 

i would make a new class define the enum, and then instantiate supported colours as

vector<colorEnumClass> supportedColours

you can then do things like : give the class methods for testing a colour to see if it is a member of the vector .. then you can use that method in IF statements rather than explicit testing using relational operators. Clearer coding :-)

notice that the name supportedColours suggests that this vector should be a constant, defined at program start and never changed. If this is the case then the "colours" in the vector should be set in the constructor and never changed. The class should be implemented as a Singleton and you might even override the vector operators of pushback() etc to block modifications.

This is in the nature of the "new" Java enumeration technology

i should also mention that i am too new to Objective C to provide a syntactically correct code example .. sorry.

vulcan_
The question wasn't about solutions in C++ - `vector<colorEnumClass>` is a C++ example of what he wants to do in ObjC.
Georg Fritzsche
A: 

You are perhaps looking for a way to simply loop through all of the options? How about just a plan old normal array?

typedef enum {RED,BLUE,GREEN,YELLOW} color;

color colors[4]={RED,YELLOW,GREEN,BLUE};
for (int i=0;i<4;i++)
    colors[i];

On the other hand if performance isn't an issue and you are just looking to clean up the code a little; how about creating a class ColorArray that encapsulates NSMutableArray and creates the relevant methods.

ColorArray.h:

#import <Foundation/Foundation.h>

typedef enum {RED,BLUE,GREEN,YELLOW} Color;

@interface ColorArray : NSObject {
    NSMutableArray* _array;
}

- (id) initWithArray:(Color[])colors;

- (void) addColor:(Color)color;
- (Color) colorAtIndex:(int)i;

@end

ColorArray.c:

#import "ColorArray.h"

@implementation ColorArray

- (id) init {
    if (self = [super init]) {
        _array = [[NSMutableArray alloc] init];
    }
    return self;
}
- (id) initWithArray:(Color[])colors {
    if (self = [super init]) {
        _array = [[NSMutableArray alloc] init];
        for (int i=0;colors[i]!=0;i++)
            [_array addObject:[NSNumber numberWithInt:colors[i]]];
    }
    return self;
}
- (void) dealloc {
    [_array release];
    [super dealloc];
}

- (void) addColor:(Color)color {
    [_array addObject:[NSNumber numberWithInt:color]];
}
- (Color) colorAtIndex:(int)i {
    return [[_array objectAtIndex:i] intValue];
}

@end
aepryus