Comment définir et utiliser un ENUM en Objective-C?


180

J'ai déclaré une énumération dans mon fichier d'implémentation comme indiqué ci-dessous, et déclaré une variable de ce type dans mon interface en tant que PlayerState thePlayerState; et utilisé la variable dans mes méthodes. Mais j'obtiens des erreurs indiquant que ce n'est pas déclaré. Comment déclarer et utiliser correctement une variable de type PlayerState dans mes méthodes?:

Dans le fichier .m

@implementation View1Controller

    typedef enum playerStateTypes
        {
            PLAYER_OFF,
            PLAYER_PLAYING,
            PLAYER_PAUSED
        } PlayerState;

dans le fichier .h:

@interface View1Controller : UIViewController {

    PlayerState thePlayerState;

dans une méthode dans un fichier .m:

-(void)doSomethin{

thePlayerState = PLAYER_OFF;

}

2
Maintenant, le type de l'énumération est lePlayerState. Que devient playerStateTypes?
user4951

3
Pour plus d'informations sur NS_ENUM et sa dernière syntaxe moderne, consultez l'article NS_ENUM & NS_OPTIONS de Mattt Thompson.
Basil Bourque

Réponses:


109

Vous typedefdevez être dans le fichier d'en-tête (ou dans un autre fichier qui est #importinséré dans votre en-tête), car sinon le compilateur ne saura pas quelle taille créer l' PlayerStateivar. A part ça, ça me va.


L'option de le mettre dans un fichier séparé me semblait juste dans mon cas. Je ne sais pas si c'est une bonne approche, mais j'avais besoin d'utiliser la même énumération dans deux ViewControllers différents (self et son délégué / source de données). L'importation de l'en-tête du délégué / de la source de données a entraîné une erreur et semble trop pour un simple besoin. J'ai donc créé un nouveau fichier .h avec l'énumération déclarée et je l'ai importé sur les deux fichiers viewControllers.h. A travaillé comme un charme.
Leandro Alves

7
Devrait recommander d'utiliser la macro NS_ENUM - puisque c'est la meilleure pratique
khebbie

1
Vous devez déclarer NS_ENUMles énumérations en Objective-C si vous voulez que votre énumération soit disponible en code Swift.
smileyborg

@DaveDeLong, est-ce toujours valable en 2015? J'ai le typedefdéclaré dans le .mfichier et il se compile et fonctionne bien.
Iulian Onofrei

@IulianOnofrei il irait dans le fichier .h si vous avez besoin d'utiliser l'énumération dans d'autres fichiers. Si vous n'en avez besoin que dans un seul fichier, le mettre dans le fichier .m a toujours été parfaitement bien.
Dave DeLong

206

Apple propose une macro pour améliorer la compatibilité du code, y compris Swift. L'utilisation de la macro ressemble à ceci.

typedef NS_ENUM(NSInteger, PlayerStateType) {
  PlayerStateOff,
  PlayerStatePlaying,
  PlayerStatePaused
};

Documenté ici


Les Enums Obj C peuvent-ils avoir des variables membres comme ils le peuvent en Java? Si c'est le cas, comment?
horloger

La deuxième solution est donc meilleure?
Iulian Onofrei

3
La deuxième solution est meilleure (en utilisant NS_ENUM), car elle est plus moderne et est désormais requise en Objective-C si vous souhaitez que votre énumération soit disponible en code Swift.
smileyborg

Mise à jour pour montrer que la deuxième solution est en fait meilleure.
rebelzach

Dans la forme standard d'Apple, le nom du type est répété pour chaque valeur d'énumération.
ThomasW

29

Dans le .h:

typedef enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
} PlayerState;

1
Vous pouvez trouver une réponse comme celle-ci dans d'autres questions SO, mais lorsque j'ai examiné les énumérations, cette question est apparue en premier, j'ai donc ajouté la réponse ici aussi.
Ben Flynn

19

Avec les projets en cours, vous souhaiterez peut-être utiliser les macros NS_ENUM()ou NS_OPTIONS().

typedef NS_ENUM(NSUInteger, PlayerState) {
        PLAYER_OFF,
        PLAYER_PLAYING,
        PLAYER_PAUSED
    };

2
... et plus important encore, vous devez déclarer NS_ENUMles énumérations en utilisant Objective-C si vous voulez que votre énumération soit disponible en code Swift.
smileyborg

16

Voici comment Apple le fait pour des classes comme NSString:

Dans le fichier d'en-tête:

enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
};

typedef NSInteger PlayerState;

Reportez-vous aux directives de codage sur http://developer.apple.com/


3
Cela n'aide pas réellement l'OP. Bien que techniquement correct, il ne leur dit pas comment créer une énumération réutilisable
RyanR

24
Créer un lien vers developer.apple.com n'est pas vraiment utile. Y a-t-il un autre endroit que vous aimeriez citer à la place?
Brett

Copier / coller la documentation qui a déjà donné, le lien qui est la page principale n'aide vraiment pas à une autre personne ...
Onder OZCAN

3
Ceci est maintenant obsolète, voir cette page developer.apple.com/library/ios/releasenotes/ObjectiveC/…
Alex Chesters

8

Je recommande d'utiliser NS_OPTIONS ou NS_ENUM. Vous pouvez en savoir plus ici: http://nshipster.com/ns_enum-ns_options/

Voici un exemple de mon propre code utilisant NS_OPTIONS, j'ai un utilitaire qui définit une sous-couche (CALayer) sur la couche d'un UIView pour créer une bordure.

Le H. fichier:

typedef NS_OPTIONS(NSUInteger, BSTCMBorder) {
    BSTCMBOrderNoBorder     = 0,
    BSTCMBorderTop          = 1 << 0,
    BSTCMBorderRight        = 1 << 1,
    BSTCMBorderBottom       = 1 << 2,
    BSTCMBOrderLeft         = 1 << 3
};

@interface BSTCMBorderUtility : NSObject

+ (void)setBorderOnView:(UIView *)view
                 border:(BSTCMBorder)border
                  width:(CGFloat)width
                  color:(UIColor *)color;

@end

Le fichier .m:

@implementation BSTCMBorderUtility

+ (void)setBorderOnView:(UIView *)view
                 border:(BSTCMBorder)border
                  width:(CGFloat)width
                  color:(UIColor *)color
{

    // Make a left border on the view
    if (border & BSTCMBOrderLeft) {

    }

    // Make a right border on the view
    if (border & BSTCMBorderRight) {

    }

    // Etc

}

@end
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.