Question Qu'est-ce qu'un typedef enum dans Objective-C?


Je ne pense pas que je comprends fondamentalement ce que enum est, et quand l'utiliser.

Par exemple:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

Qu'est-ce qui est vraiment déclaré ici?


1042
2018-04-01 21:59


origine


Réponses:


Trois choses sont déclarées ici: un type énuméré anonyme est déclaré, ShapeType est déclaré un typedef pour cette énumération anonyme, et les trois noms kCircle, kRectangle, et kOblateSpheroid sont déclarés comme constantes intégrales.

Brisons-le. Dans le cas le plus simple, une énumération peut être déclarée comme

enum tagname { ... };

Ceci déclare une énumération avec le tag tagname. En C et Objective-C (mais ne pas C ++), toutes les références à cette doit être précédé de la enum mot-clé. Par exemple:

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

Afin d'éviter d'avoir à utiliser le enum mot-clé partout, un typedef peut être créé:

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

Cela peut être simplifié en une ligne:

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

Et enfin, si nous n'avons pas besoin d'être en mesure d'utiliser enum tagname avec le enum mot-clé, nous pouvons faire la enum anonyme et ne le déclare qu'avec le nom de typedef:

typedef enum { ... } tagname;

Maintenant, dans ce cas, nous déclarons ShapeType être un nom typé d'une énumération anonyme. ShapeType est vraiment juste un type intégral, et ne devrait être utilisé que pour déclarer des variables qui contiennent l'une des valeurs listées dans la déclaration (c'est-à-dire kCircle, kRectangle, et kOblateSpheroid). Vous pouvez attribuer un ShapeType variable une autre valeur en moulant, cependant, donc vous devez être prudent lors de la lecture des valeurs enum.

Finalement, kCircle, kRectangle, et kOblateSpheroid sont déclarées comme des constantes intégrales dans l'espace de noms global. Comme aucune valeur spécifique n'a été spécifiée, ils sont affectés à des entiers consécutifs commençant par 0, donc kCircle est 0, kRectangle est 1, et kOblateSpheroid est 2.


1532
2018-04-01 22:22



Apple recommande de définir des énumérations comme celle-ci depuis Xcode 4.4:

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

Ils fournissent également une macro pratique. NS_ENUM:

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

Ces définitions fournissent une vérification de type plus forte et une meilleure complétion de code. Je n'ai pas pu trouver une documentation officielle de NS_ENUM, mais vous pouvez visionner la vidéo "Modern Objective-C" de la session de la WWDC 2012 ici.

MISE À JOUR: Lien vers la documentation officielle ici.


240
2018-03-06 09:43



Une énumération déclare un ensemble de valeurs ordonnées - le typedef ajoute juste un nom pratique à ceci. Le 1er élément est 0 etc.

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

WORKDAYS today = Monday;

Ce qui précède est juste une énumération des balises shapeType.


47
2018-03-15 16:31



Un type défini par l'utilisateur qui a les valeurs possibles de kCircle, kRectangle, ou kOblateSpheroid. Les valeurs à l'intérieur de l'enum (kCircle, etc.) sont visibles en dehors de l'énumération. Il est important de garder cela à l'esprit (int i = kCircle; est valide, par exemple).


34
2018-04-01 22:04



Mise à jour pour le changement 64 bits: Selon Docs apple à propos des changements de 64 bits,

Les énumérations sont également typées: Dans le compilateur LLVM, les types énumérés peuvent   définir la taille de l'énumération. Cela signifie que certains énumérés   Les types peuvent également avoir une taille supérieure à celle que vous attendez. le   solution, comme dans tous les autres cas, est de ne faire aucune hypothèse sur un   taille du type de données. Au lieu de cela, affectez toutes les valeurs énumérées à une variable   avec le bon type de données

Donc vous devez créer enum avec type comme ci-dessous la syntaxe si vous soutenez pour 64 bits.

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

ou

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

Sinon, cela conduira à un avertissement Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType

Mise à jour pour la programmation rapide:

En swift, il y a un changement de syntaxe.

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

28
2018-01-29 13:08



Enum est un type de données défini par l'utilisateur. TYPES DE DONNÉES ENUMÉRÉS Les variables de type de données énumérées peuvent uniquement supposer des valeurs qui ont été déclarées précédemment.

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

this_month = feb;

Dans la déclaration ci-dessus, mois est déclaré comme un type de données énuméré. Il se compose d'un ensemble de valeurs, jan à dec. Numériquement, jan reçoit la valeur 1, feb la valeur 2, et ainsi de suite.

La variable this_month est déclarée être du même type que le mois, puis est affectée la valeur associée à feb. This_month ne peut pas recevoir de valeurs autres que celles spécifiées dans la liste d'initialisation pour la déclaration du mois.


25
2017-10-17 12:08



L'énumération (abréviation d'énumération) est utilisée pour énumérer un ensemble de valeurs (énumérateurs). Une valeur est une chose abstraite représentée par un symbole (un mot). Par exemple, une énumération de base pourrait être

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

Cette énumération est appelée anonyme parce que vous n'avez pas de symbole pour la nommer. Mais c'est toujours parfaitement correct. Il suffit de l'utiliser comme ça

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

D'accord. La vie est belle et tout va bien. Mais un jour, vous devez réutiliser cette énumération pour définir une nouvelle variable pour stocker myGrandFatherPantSize, puis vous écrivez:

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

Mais alors vous avez une erreur de compilation "redéfinition de l'énumérateur". En fait, le problème est que le compilateur n'est pas sûr que vous enumez en premier et votre deuxième décrit la même chose.

Ensuite, si vous voulez réutiliser le même ensemble d'énumérateurs (ici xs ... xxxxl) à plusieurs endroits, vous devez le marquer avec un nom unique. La deuxième fois que vous utilisez cet ensemble, vous devez simplement utiliser l'étiquette. Mais n'oubliez pas que cette balise ne remplace pas le mot enum mais seulement l'ensemble des énumérateurs. Ensuite, prenez soin d'utiliser enum comme d'habitude. Comme ça:

// 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;

vous pouvez également l'utiliser dans une définition de paramètre:

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

On pourrait dire que réécrire enum partout n'est pas pratique et rend le code un peu étrange. Tu as raison. Un vrai type serait mieux.

C'est la dernière étape de notre grande progression vers le sommet. En ajoutant simplement un typedef, transformons notre énumération en un type réel. Oh une dernière chose, typedef n'est pas autorisé dans votre classe. Puis définissez votre type juste au-dessus. Fais-le comme ça:

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

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

Rappelez-vous que la balise est facultative. Puis puisque ici, dans ce cas, nous ne devons pas marquer les énumérateurs, mais simplement définir un nouveau type. Ensuite, nous n'en avons plus vraiment besoin.

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

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

Si vous développez en ObjectiveC avec XCode, je vous laisse découvrir de jolies macros préfixées par NS_ENUM. Cela devrait vous aider à définir de bonnes énumérations facilement et, de plus, aidera l'analyseur statique à faire des vérifications intéressantes avant de compiler.

Bon Enum!


23
2018-03-10 18:23



typedef est utile pour redéfinir le nom d'un type de variable existant. Il fournit un moyen court et significatif d'appeler un type de données. par exemple:

typedef unsigned long int TWOWORDS;

ici, le type unsigned long int est redéfini pour être du type TWOWORDS. Ainsi, nous pouvons maintenant déclarer des variables de type unsigned long int en écrivant,

TWOWORDS var1, var2;

au lieu de

unsigned long int var1, var2;

10
2018-06-18 06:03



typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;

alors vous pouvez l'utiliser comme: -

 ShapeType shape;

et

 enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} 
ShapeType;

maintenant vous pouvez l'utiliser comme: -

enum ShapeType shape;

6
2017-12-25 06:14



enum est utilisé pour assigner une valeur aux éléments enum qui ne peuvent pas être faits dans struct. Donc, à chaque fois, au lieu d'accéder à la variable complète, nous pouvons le faire par la valeur que nous affectons aux variables dans enum. Par défaut, il commence par l'affectation 0, mais nous pouvons lui affecter n'importe quelle valeur et la variable suivante dans enum se verra attribuer une valeur de la valeur précédente +1.


4
2018-03-16 12:45