tags:

views:

485

answers:

4

Hi,

I am new to Obj-C so forgive me if this is a stupid question:

How do I implement some in the style of Javas enums? Or to be more precise:

I want a class with some known properties which are fix at compile time and unique per instance. Additionally I only want one instance type.

Let me give an example in Java:

public enum MessageTypes {
  DEFAULT("white", "standard", 1),
  EXPRESS("red", "expressMessage", 2),
  BORADCAST("green", "broadcast", 3);

  String color; String tagName; int dbId;
  MessageTypes(String color, String tagName, int dbId) {
    // you get the idea
  }
  //some methonds like getEnumByTagName
}

How would you do something like this in Objective-C? Am I missing something? Is this a bad pattern at all?

Thanks in advance!

EDIT: I am sorry, if I did not made myself clear. I know, that obj-c enums are not what I am looking for (as they are only marginally more than a typedef to an int).

I would like to create a set of (kind-of-singleton, immutable) instances of a specific class. The singleton pattern in Apples Dev-Docs is of no use as I want multiple distinct instances of a class each with individual values in their properties.

The goal of that is to have multiple Message types (about 20) that can be assigned to a Message as a property. Each of my Message types has a (fix and predefined) color, attribute-value (in an XML-representation) and a numerical ID.

In Java, I would use an enum as in my code sample. But how do I create different MessageTypes and associate them with their properties in Obj-C?

Creating 20 Sublcasses of MessageType (each with a singleton-instance holding the properties) seems like a lot of work for such a simple task and total overkill.

My current approach is to create a class with an NSArray holding the different instances. Up on first access of a method like +(id)messageTypeForId:NSInteger id_ the NSArray is prepopulated. But this feels totally clumsy and not at all elegant...

Is there a more satisfying approach?

A: 

I think I'd just use a standard C enum:

typedef enum { MT_WHITE, MT_RED, MT_GREEN } MessageType;

Then you just use it as you would any other data type:

@interface Blah {}

-(void) setMessageType:(MessageType)newMessageType;

@end
Stephen Darlington
Well, then I don't get my properties, that are unique per instance.
Mo
+1  A: 

Enums are not objects in C, and thus not in Objective-C either. They're just user-defined scalars that have a limited set of named values that they can take. You can give an object properties that are enum types, which I think is closest to what you're looking for.

If there's something specific you need to accomplish with this functionality, you might want to edit your post to indicate what that is.

Chuck
+1  A: 

There is not much in the way of a "more satisfying approach".

The normal Cocoa pattern would be to create methods like:

+ (MessageTypes*) sharedDefaultMessageType;
+ (MessageTypes*) sharedExpressMessageType;
+ (MessageTypes*) sharedBroadcastMessageType;
etc

and then implement them something like:

+ (MessageTypes*) sharedDefaultMessageType
{
   static MessageTypes* thisMessageType = nil;
   if ( !thisMessageType ) {
      thisMessageType = [[MessageTypes alloc] initWithColor:@"white" tagName:@"standard" dbId:1];
   }
   return thisMessageType;
}

Alternatively, storing the shared MessageType* in an NSMutableArray or NSMutableDictionary or precalculating them as you are doing are all equally valid approraches.

Note that the above "template" method could be generated via a macro such that you could write in the .m file:

CREATEMESSAGETYPE( Default, @"white", @"standard", 1 )
CREATEMESSAGETYPE( Express, @"red", @"expressMessage", 2 )
CREATEMESSAGETYPE( Broadcast, @"green", @"broadcast", 3 )

which might be "more satisfying" or more ugly, depending on your point of view.

Peter N Lewis
The macro is more ugly in my point of view but I really like your first solution. That appears to be better (and more cocoa-like) than my approach. Thank you.
Mo
I see how `default` and `shared` are used by convention in some classes, are there other other prefixes like those?
zekel
A: 

I had the same question more or less but find all the above solutions clumsy stylistically. In particular when simply using a C enum property on an object you lose the singleton semantics of Java enums. The biggest freedom I have found in the use of Java enums is that the instances of an enum are really singleton subclasses, and so participate in method polymorphism. Even more powerful than enums with unique attributes is enums with polymorphic behaviour.

Given that this is the key feature I am after would an Objective-C class cluster with singleton private subclasses be an approach with the desired behaviour, despite being a bit over the top in implementation cost and complexity?

Dave Whitla