it-swarm.com.de

Was ist eine typedef-Aufzählung in Objective-C?

Ich glaube nicht, dass ich im Grunde verstehe, was ein enum ist und wann man es verwendet.

Zum Beispiel:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

Was wird hier wirklich deklariert?

1080
Craig

Hier werden drei Dinge deklariert: Ein anonymer Aufzählungstyp wird deklariert, ShapeType wird als Typedef für diese anonyme Aufzählung deklariert, und die drei Namen kCircle, kRectangle und kOblateSpheroid werden als integrale Konstanten deklariert.

Lassen Sie uns das aufschlüsseln. 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++) muss vor allen Verweisen auf muss das Schlüsselwort enum stehen. Zum Beispiel:

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

Um zu vermeiden, dass das Schlüsselwort enum überall verwendet werden muss, kann ein typedef erstellt werden:

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

Dies kann in einer Zeile vereinfacht werden:

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

Und schließlich können wir, wenn wir enum tagname nicht mit dem enum-Schlüsselwort verwenden müssen, das enum anonymisieren und es nur mit dem typedef-Namen deklarieren:

typedef enum { ... } tagname;

In diesem Fall deklarieren wir ShapeType als typisierten Namen einer anonymen Aufzählung. ShapeType ist eigentlich nur ein ganzzahliger Typ und sollte nur zum Deklarieren von Variablen verwendet werden, die einen der in der Deklaration aufgelisteten Werte enthalten (dh einen von kCircle, kRectangle und kOblateSpheroid). Sie können einer ShapeType -Variablen jedoch einen anderen Wert zuweisen, indem Sie sie umwandeln. Daher müssen Sie beim Lesen von Aufzählungswerten vorsichtig sein.

Schließlich werden kCircle, kRectangle und kOblateSpheroid als integrale Konstanten im globalen Namespace deklariert. Da keine spezifischen Werte angegeben wurden, werden sie aufeinanderfolgenden Ganzzahlen zugewiesen, die mit 0 beginnen. Daher ist kCircle 0, kRectangle 1 und kOblateSpheroid 2.

1559
Adam Rosenfield

Apple empfiehlt, Enums wie dieses seit Xcode 4.4 zu definieren:

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

Sie bieten auch ein handliches Makro NS_ENUM:

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

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

UPDATE: Link zur offiziellen Dokumentation hier .

251

Eine Aufzählung deklariert eine Reihe von geordneten Werten - die typedef fügt diesem lediglich einen praktischen Namen hinzu. Das 1. Element ist 0 usw.

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

WORKDAYS today = Monday;

Das Obige ist nur eine Aufzählung von shapeType-Tags.

51
hburde

Ein benutzerdefinierter Typ mit den möglichen Werten kCircle, kRectangle oder kOblateSpheroid. Die Werte innerhalb der Aufzählung (kCircle usw.) sind jedoch außerhalb der Aufzählung sichtbar. Beachten Sie dies unbedingt (int i = kCircle; ist beispielsweise gültig).

34
Brian Mitchell

Update für 64-Bit-Änderung: Laut Apple-Dokumentation über 64-Bit-Änderungen,

Aufzählungen werden auch typisiert: Im LLVM-Compiler können Aufzählungstypen die Größe der Aufzählung definieren. Dies bedeutet, dass einige Aufzählungstypen möglicherweise auch eine größere Größe haben als erwartet. Die Lösung besteht, wie in allen anderen Fällen, darin, keine Annahmen über die Größe eines Datentyps zu treffen. Weisen Sie stattdessen einer Variablen mit dem richtigen Datentyp alle aufgezählten Werte zu

Sie müssen also eine Aufzählung mit dem folgenden Typ erstellen, wenn Sie 64-Bit unterstützen.

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

oder

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

Andernfalls wird eine Warnung ausgegeben, wenn Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType

Update für Swift-Programmierung:

In Swift gibt es eine Syntaxänderung.

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

Die Aufzählung (Abkürzung für Enumeration) wird zum Aufzählen einer Reihe von Werten (Enumeratoren) verwendet. Ein Wert ist eine abstrakte Sache, die durch ein Symbol (ein Wort) dargestellt wird. Zum Beispiel könnte eine einfache Aufzählung sein

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

Diese Aufzählung wird anonym genannt, 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;

Okay. Das Leben ist schön und alles geht 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 besteht das Problem darin, dass der Compiler nicht sicher ist, ob Sie die erste Aufzählung und die zweite das Gleiche beschreiben.

Wenn Sie denselben Satz von Enumeratoren (hier xs ... xxxxl) an mehreren Stellen wiederverwenden möchten, müssen Sie ihn mit einem eindeutigen Namen versehen. Wenn Sie dieses Set zum zweiten Mal verwenden, müssen Sie nur das Tag verwenden. Vergessen Sie jedoch nicht, dass dieses Tag nicht das Aufzählungswort ersetzt, sondern nur die Aufzählungsmenge. Achten Sie dann 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 der Enumeration überall nicht praktisch ist und den Code etwas seltsam erscheinen lässt. Du hast recht. Ein echter Typ wäre besser.

Dies ist der letzte Schritt unseres großen Fortschritts zum Gipfel. Indem wir nur ein typedef hinzufügen, wandeln wir unsere Aufzählung in einen echten Typ um. Oh das letzte, typedef ist in deiner Klasse nicht erlaubt. Dann definieren Sie 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. In diesem Fall markieren wir die Enumeratoren nicht, sondern definieren nur einen neuen Typ. Dann brauchen wir es nicht mehr wirklich.

// 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 Objective-C mit XCode entwickeln, lassen Sie einige Nice-Makros mit dem Präfix NS_ENUM entdecken. Das sollte Ihnen helfen, gute Enums einfach zu definieren, und außerdem hilft es dem statischen Analysator, einige interessante Überprüfungen durchzuführen, bevor Sie kompilieren.

Gutes Enum!

24
Vincent Zgueb

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

typedef unsigned long int TWOWORDS;

hier wird der Typ unsigned long int neu definiert und vom Typ TWOWORDS. So können wir jetzt Variablen vom Typ unsigned long int deklarieren, indem wir schreiben,

TWOWORDS var1, var2;

anstatt von

unsigned long int var1, var2;
10
Rajneesh071
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;
7
Vivek Sehrawat

enum wird verwendet, um enum-Elementen einen Wert zuzuweisen, der in struct nicht möglich ist. Anstatt auf die gesamte Variable zuzugreifen, können wir dies also jedes Mal mit dem Wert tun, den wir den Variablen in enum zuweisen. Standardmäßig beginnt es mit der Zuweisung von 0, aber wir können ihm einen beliebigen Wert zuweisen und der nächsten Variablen in enum wird ein Wert zugewiesen, der dem vorherigen Wert +1 entspricht.

3
Priyanka Naik

Ein typedef ermöglicht es dem Programmierer, einen Objective-C-Typ als einen anderen zu definieren. Zum Beispiel,

typedef int Counter; Definiert den Typzähler so, dass er dem int-Typ entspricht. Dies verbessert die Lesbarkeit des Codes drastisch.

2
user4398701

Das Typedef ist ein Schlüsselwort in C und C++. Es wird verwendet, um neue Namen für Basisdatentypen zu erstellen (char, int, float, double, struct & enum).

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

Hier wird der Aufzählungsdatentyp ShapeType erstellt und wir können neue Namen für den Aufzählungstyp ShapeType wie unten angegeben schreiben

ShapeType shape1; 
ShapeType shape2; 
ShapeType shape3;
2
Yogeesh H T

Sie können im folgenden Format den Raw-Standardwert ab 0 verwenden, also

  • kCircle ist 0,
  • kRectangle ist 1,
  • kOblateSpheroid ist 2.

Sie können Ihren eigenen spezifischen Startwert zuweisen.

typedef enum : NSUInteger {
    kCircle, // for your value; kCircle = 5, ...
    kRectangle,
    kOblateSpheroid
} ShapeType;

ShapeType circleShape = kCircle;
NSLog(@"%lu", (unsigned long) circleShape); // prints: 0
2
Bilal Arslan

enum kann viele Arten von "Fehlern" reduzieren und den Code übersichtlicher machen

#define STATE_GOOD 0
#define STATE_BAD 1
#define STATE_OTHER 2
int STATE = STATE_OTHER

Die Definition unterliegt keinen Einschränkungen. Es ist einfach nur ein Ersatz. Es ist nicht in der Lage, alle Zustände des Staates einzuschränken. Wenn der Status 5 zugewiesen ist, ist das Programm falsch, da es keinen passenden Status gibt. Der Compiler warnt jedoch nicht vor STATE = 5

Also ist es besser, so zu verwenden

typedef enum SampleState {
    SampleStateGood  = 0,
    SampleStateBad,
    SampleStateOther
} SampleState;

SampleState state = SampleStateGood;
0
Marcus Thornton