2009-06-10 5 views
13

Ich bin neu in Obj-C also vergib mir, wenn das eine dumme Frage ist:Java-enum Stilklassen in Objective-C?

Wie implementiere ich etwas im Stil von Javas enums? Oder um genauer zu sein:

Ich möchte eine Klasse mit einigen bekannten Eigenschaften, die zur Kompilierzeit fest und einzigartig pro Instanz sind. Zusätzlich möchte ich nur einen Instanztyp.

Lassen Sie mich ein Beispiel in Java geben:

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 
} 

Wie würden Sie so etwas wie dies in Objective-C tun? Fehle ich etwas? Ist das überhaupt ein schlechtes Muster?

Vielen Dank im Voraus!

EDIT: Es tut mir leid, wenn ich mich nicht klar gemacht habe. Ich weiß, dass obj-c enums nicht das sind, was ich suche (da sie nur marginal mehr sind als ein typedef zu einem int).

Ich möchte eine Reihe von (Art-of-Singleton, unveränderlich) Instanzen einer bestimmten Klasse erstellen. Das Singleton-Muster in Apples Dev-Docs ist nutzlos, da ich mehrere unterschiedliche Instanzen einer Klasse mit jeweils individuellen Werten in ihren Eigenschaften haben möchte.

Ziel ist es, mehrere Nachrichtentypen (ca. 20) zu haben, die einer Nachricht als Eigenschaft zugewiesen werden können. Jeder meiner Nachrichtentypen hat eine (fixe und vordefinierte) Farbe, einen Attributwert (in einer XML-Darstellung) und eine numerische ID.

In Java würde ich eine enum wie in meinem Codebeispiel verwenden. Aber wie erstelle ich verschiedene MessageTypes und verknüpfe sie mit ihren Eigenschaften in Obj-C?

Das Erstellen von 20 Subtcases von MessageType (jede mit einer Singleton-Instanz, die die Eigenschaften enthält) scheint für eine so einfache Aufgabe und einen totalen Overkill viel Arbeit zu sein.

Meine aktuelle Vorgehensweise besteht darin, eine Klasse mit einem NSArray zu erstellen, das die verschiedenen Instanzen enthält. Beim ersten Zugriff einer Methode wie +(id)messageTypeForId:NSInteger id_ ist das NSArray vorbelegt. Aber das fühlt sich total tollpatschig an und überhaupt nicht elegant ...

Gibt es einen befriedigenderen Ansatz?

Antwort

7

Einem "befriedigenderen Ansatz" steht nicht viel im Wege.

würde die normale Cocoa Muster wie Methoden erstellen sein:

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

und sie dann wie etwas implementieren:

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

Alternativ kann in einem NSMutableArray oder NSMutableDictionary oder Vorberechnung die gemeinsame Message * Speichern Sie, wie Sie es tun, sind alle gleichgültige Appraches.

Beachten Sie, dass die oben „Vorlage“ Methode über einen Makro erzeugt werden könnte, so dass Sie in der .m-Datei schreiben können:

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

die „befriedigende“ oder mehr hässlich sein könnte, abhängig von Ihrer Standpunkt.

+0

Das Makro ist meiner Meinung nach hässlicher, aber ich mag deine erste Lösung. Das scheint besser (und kakaoartiger) zu sein als mein Ansatz. Vielen Dank. –

+0

Ich sehe, wie 'default' und' shared' per Konvention in einigen Klassen verwendet werden, gibt es andere andere Präfixe wie diese? – zekel

+0

In Ihrer ersten Lösung, warum überprüfen Sie, ob thisMessageType vor dem Aufrufen von Allo nil ist? Wird es nicht immer Null wegen der vorhergehenden Zeile sein? Danke für die Hilfe eines Neulings. –

1

Ich glaube, ich nur eine Standard-C-Enumeration verwenden würde:

typedef enum { MT_WHITE, MT_RED, MT_GREEN } MessageType; 

Dann nutzen Sie es einfach wie jeder anderen Datentyp:

@interface Blah {} 

-(void) setMessageType:(MessageType)newMessageType; 

@end 
+4

Nun, dann bekomme ich meine Eigenschaften nicht, die für jede Instanz eindeutig sind. –

0

Aufzählungen sind keine Objekte in C, und somit auch nicht in Objective-C. Sie sind nur benutzerdefinierte Skalare, die eine begrenzte Anzahl von benannten Werten haben, die sie verwenden können. Sie können Objekteigenschaften angeben, die Enum-Typen sind, die Ihrer Meinung nach am nächsten sind.

Wenn es etwas Bestimmtes gibt, das Sie mit dieser Funktionalität erreichen müssen, möchten Sie vielleicht Ihren Post bearbeiten, um anzuzeigen, was das ist.

0

Ich hatte die gleiche Frage mehr oder weniger, finde aber alle oben genannten Lösungen unbeholfen stilistisch. Insbesondere wenn Sie einfach eine C enum-Eigenschaft für ein Objekt verwenden, verlieren Sie die Singleton-Semantik von Java-Enums. Die größte Freiheit, die ich bei der Verwendung von Java-Enums gefunden habe, besteht darin, dass die Instanzen eines Enums wirklich Singleton-Unterklassen sind und so am Methodenpolymorphismus teilnehmen. Noch mächtiger als Enums mit einzigartigen Attributen sind Enums mit polymorphem Verhalten.

Vorausgesetzt, dass dies das Schlüsselfeature ist, nach dem ich ein Objective-C-Klassencluster mit Singleton private Unterklassen ein Ansatz mit dem gewünschten Verhalten wäre, obwohl ein bisschen über die Kosten und Komplexität der Implementierung ist?

Verwandte Themen