Frage Was ist eine Typedef Enum in Objective-C?


Ich glaube nicht, dass ich grundsätzlich verstehe was enum ist, und wann man es benutzt.

Beispielsweise:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

Was wird hier wirklich erklärt?


1042
2018-04-01 21:59


Ursprung


Antworten:


Drei Dinge werden hier deklariert: ein anonymer Aufzählungstyp wird deklariert, ShapeType wird für diese anonyme Enumeration als Typdef und die drei Namen deklariert kCircle, kRectangle, und kOblateSpheroid werden als Integralkonstanten deklariert.

Lass uns das durchbrechen. Im einfachsten Fall kann eine Aufzählung als deklariert werden

enum tagname { ... };

Dies deklariert eine Aufzählung mit dem Tag tagname. In C und Objective-C (aber nicht C ++), irgendwelche Hinweise darauf Muss vorausgegangen sein enum Stichwort. Beispielsweise:

enum tagname x;  // declare x of type 'enum tagname'
tagname x;  // ERROR in C/Objective-C, OK in C++

Um zu vermeiden, dass Sie die enum Stichwort überall, ein typedef kann erstellt werden:

enum tagname { ... };
typedef enum tagname tagname;  // declare 'tagname' as a typedef for 'enum tagname'

Dies kann in eine Zeile vereinfacht werden:

typedef enum tagname { ... } tagname;  // declare both 'enum tagname' and 'tagname'

Und schließlich, wenn wir nicht in der Lage sein müssen zu verwenden enum tagname mit dem enum Stichwort, wir können das machen enum anonym und deklariere es nur mit dem typedef-Namen:

typedef enum { ... } tagname;

Jetzt, in diesem Fall, erklären wir ShapeType ein typdefinierter Name einer anonymen Aufzählung sein. ShapeType ist eigentlich nur ein ganzzahliger Typ und sollte nur verwendet werden, um Variablen zu deklarieren, die einen der in der Deklaration aufgeführten Werte enthalten (also einen von kCircle, kRectangle, und kOblateSpheroid). Sie können a zuweisen ShapeType Variiere jedoch einen anderen Wert, indem du umlegst, also musst du beim Lesen von Enum-Werten vorsichtig sein.

Endlich, kCircle, kRectangle, und kOblateSpheroid werden im globalen Namensraum als Integralkonstanten deklariert. Da keine spezifischen Werte angegeben wurden, werden sie fortlaufenden Ganzzahlen zugewiesen, die mit 0 beginnen, also kCircle ist 0, kRectangle ist 1, und kOblateSpheroid ist 2.


1532
2018-04-01 22:22



Apple empfiehlt, solche Enums seit Xcode 4.4 zu definieren:

typedef enum ShapeType : NSUInteger {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

Sie bieten auch ein praktisches Makro NS_ENUM:

typedef NS_ENUM(NSUInteger, ShapeType) {
    kCircle,
    kRectangle,
    kOblateSpheroid
};

Diese Definitionen bieten eine stärkere Typprüfung und bessere Code-Vervollständigung. Ich konnte keine offizielle Dokumentation von NS_ENUM finden, aber Sie können sich das Video "Modern Objective-C" von der WWDC 2012-Sitzung anschauen Hier.

UPDATE: Link zur offiziellen Dokumentation Hier.


240
2018-03-06 09:43



Ein enum deklariert eine Menge von geordneten Werten - der Typdef fügt nur einen handlichen Namen hinzu. Das erste Element ist 0 usw.

typedef enum {
Monday=1,
...
} WORKDAYS;

WORKDAYS today = Monday;

Das obige ist nur eine Aufzählung von ShapeType-Tags.


47
2018-03-15 16:31



Ein benutzerdefinierter Typ mit den möglichen Werten von kCircle, kRectangle, oder kOblateSpheroid. Die Werte in der Enumeration (kCircle usw.) sind jedoch außerhalb der Enumeration sichtbar. Es ist wichtig, dies im Hinterkopf zu behalten (int i = kCircle; ist zum Beispiel gültig).


34
2018-04-01 22:04



Update für 64-Bit-Änderung: Gemäß Apple-Dokumente etwa 64-Bit-Änderungen,

Aufzählungen werden auch typisiert: Im LLVM-Compiler können Aufzählungstypen   Definieren Sie die Größe der Aufzählung. Dies bedeutet, dass einige aufgezählt sind   Typen können auch eine Größe haben, die größer ist als erwartet. Das   Wie in allen anderen Fällen auch, ist es keine Lösung, a   Datentyp Größe. Ordnen Sie stattdessen alle aufgelisteten Werte einer Variablen zu   mit dem richtigen Datentyp

Also musst du Erstellen Sie Enum mit Typ wie unten Syntax, wenn Sie für 64-Bit unterstützen.

typedef NS_ENUM(NSUInteger, ShapeType) {
    kCircle,
    kRectangle,
    kOblateSpheroid
};

oder

typedef enum ShapeType : NSUInteger {
   kCircle,
   kRectangle,
   kOblateSpheroid
} ShapeType;

Sonst wird es zu einer Warnung als führen Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType

Update für die schnelle Programmierung:

In swift gibt es eine Syntaxänderung.

enum ControlButtonID: NSUInteger {
        case kCircle , kRectangle, kOblateSpheroid
    }

28
2018-01-29 13:08



Enum ist benutzerdefinierter Datentyp. ENUMERIERTE DATENTYPEN Aufzählungsdatentypvariablen können nur Werte annehmen, die zuvor deklariert wurden.

enum month { jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec };
enum month this_month;

this_month = feb;

In der obigen Deklaration wird der Monat als Aufzählungsdatentyp deklariert. Es besteht aus einer Reihe von Werten, Jan bis Dec. Numerisch erhält jan den Wert 1, feb den Wert 2 und so weiter.

Die Variable this_month wird als vom Typ des Monats deklariert und dann als feb zugewiesen. This_month können keine Werte zugewiesen werden, die außerhalb der Werte liegen, die in der Initialisierungsliste für die Deklaration des Monats angegeben sind.


25
2017-10-17 12:08



Die Enumeration (Abkürzung der Enumeration) wird verwendet, um eine Reihe von Werten (Enumeratoren) aufzuzählen. Ein Wert ist eine abstrakte Sache, die durch ein Symbol (ein Wort) repräsentiert wird. Zum Beispiel könnte eine grundlegende Enum sein

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl };

Diese Enumeration wird anonym aufgerufen, da Sie kein Symbol haben, um sie zu benennen. Aber es ist immer noch vollkommen richtig. Benutze es einfach so

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;

OK. Das Leben ist schön und alles läuft gut. Aber eines Tages müssen Sie diese Enumeration wiederverwenden, um eine neue Variable zum Speichern von myGrandFatherPantSize zu definieren. Dann schreiben Sie:

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandFatherPantSize;

Aber dann haben Sie einen Compilerfehler "Neudefinition des Enumerators". Tatsächlich ist das Problem, dass der Compiler nicht sicher ist, dass Sie zuerst enum und Ihr zweites das gleiche Ding beschreiben.

Wenn Sie dann an mehreren Stellen den gleichen Satz von Enumeratoren (hier xs ... xxxxl) wiederverwenden wollen, müssen Sie ihn mit einem eindeutigen Namen versehen. Wenn Sie das Set zum zweiten Mal verwenden, müssen Sie nur das Tag verwenden. Vergessen Sie aber nicht, dass dieses Tag nicht das Enum-Wort ersetzt, sondern nur die Menge der Enumeratoren. Dann achten Sie darauf, enum wie gewohnt zu verwenden. So was:

// Here the first use of my enum
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize; 
// here the second use of my enum. It works now !
enum sizes myGrandFatherPantSize;

Sie können es auch in einer Parameterdefinition verwenden:

// Observe that here, I still use the enum
- (void) buyANewDressToMyGrandMother:(enum sizes)theSize;

Man könnte sagen, dass das Umschreiben von Enum überall nicht praktisch ist und den Code ein wenig komisch erscheinen lässt. Du hast recht. Ein echter Typ wäre besser.

Dies ist der letzte Schritt unseres großartigen Aufstiegs zum Gipfel. Indem wir einfach einen Typedef hinzufügen, transformieren wir unser enum in einen echten Typ. Oh, eine letzte Sache, typedef ist in deiner Klasse nicht erlaubt. Definieren Sie dann oben Ihren Typ. Mach es so:

// enum definition
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl };
typedef enum sizes size_type

@interface myClass {
   ...
   size_type myGrandMotherDressSize, myGrandFatherPantSize;
   ...
}

Denken Sie daran, dass das Tag optional ist. Dann müssen wir in diesem Fall die Enumeratoren nicht markieren, sondern nur einen neuen Typ definieren. Dann brauchen wir es nicht mehr.

// enum definition
typedef enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } size_type;

@interface myClass : NSObject {
  ...
  size_type myGrandMotherDressSize, myGrandFatherPantSize;
  ...
}
@end

Wenn Sie in ObjectiveC mit XCode entwickeln, lassen Sie einige nette Makros mit dem Präfix NS_ENUM erkennen. Das sollte Ihnen helfen, gute Enums einfach zu definieren und außerdem hilft Ihnen der statische Analyzer, einige interessante Checks für Sie vor dem Kompilieren durchzuführen.

Gute Aufzählung!


23
2018-03-10 18:23



typedef ist nützlich, um den Namen eines vorhandenen Variablentyps neu zu definieren. Es bietet eine kurze und sinnvolle Möglichkeit, einen Datentyp aufzurufen. z.B:

typedef unsigned long int TWOWORDS;

Hier wird der Typ unsigned long int vom Typ TWOWORDS neu definiert. So können wir jetzt Variablen vom Typ unsigned long int durch Schreiben deklarieren,

TWOWORDS var1, var2;

Anstatt von

unsigned long int var1, var2;

10
2018-06-18 06:03



typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;

dann kannst du es benutzen wie:

 ShapeType shape;

und

 enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} 
ShapeType;

Jetzt können Sie es wie folgt verwenden: -

enum ShapeType shape;

6
2017-12-25 06:14