Wie definiere und verwende ich eine ENUM in Objective-C?


180

Ich habe eine Aufzählung in meiner Implementierungsdatei wie unten gezeigt deklariert und eine Variable dieses Typs in meiner Schnittstelle als PlayerState thePlayerState deklariert. und verwendete die Variable in meinen Methoden. Aber ich bekomme Fehler, die besagen, dass es nicht deklariert ist. Wie deklariere und verwende ich eine Variable vom Typ PlayerState in meinen Methoden korrekt?:

In der .m-Datei

@implementation View1Controller

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

in der .h-Datei:

@interface View1Controller : UIViewController {

    PlayerState thePlayerState;

in einer Methode in der .m-Datei:

-(void)doSomethin{

thePlayerState = PLAYER_OFF;

}

2
Jetzt ist der Typ der Aufzählung thePlayerState. Was wird aus playerStateTypes?
user4951

3
Informationen zu NS_ENUM und seiner neuesten modernen Syntax finden Sie in der Veröffentlichung NS_ENUM & NS_OPTIONS von Mattt Thompson.
Basil Bourque

Antworten:


109

Sie typedefmüssen sich in der Header-Datei befinden (oder in einer anderen Datei, die #importin Ihrem Header enthalten ist), da der Compiler sonst nicht weiß, welche Größe der PlayerStateivar haben soll. Davon abgesehen sieht es für mich in Ordnung aus.


Die Option, es in eine separate Datei zu stellen, schien in meinem Fall richtig. Ich weiß nicht, ob dies ein guter Ansatz ist, aber ich musste dieselbe Aufzählung in zwei verschiedenen ViewControllern verwenden (self und seine Delegate / Datenquelle). Das Importieren des Headers des Delegaten / der Datenquelle führte zu einem Fehler und scheint für eine einfache Anforderung zu viel zu sein. Also habe ich eine neue .h-Datei mit der deklarierten Enumeration erstellt und in beide viewControllers.h-Dateien importiert. Lief wie am Schnürchen.
Leandro Alves

7
Sollte empfehlen, das NS_ENUM-Makro zu verwenden - da dies die beste Vorgehensweise ist
khebbie

1
Sie müssen Aufzählungen mit NS_ENUMObjective-C deklarieren, wenn Ihre Aufzählung im Swift-Code verfügbar sein soll.
Smileyborg

@ DaveDeLong, ist das 2015 noch gültig? Ich habe das typedefin der .mDatei deklariert und es kompiliert und läuft gut.
Iulian Onofrei

@IulianOnofrei würde es in die .h-Datei gehen, wenn Sie die Aufzählung in anderen Dateien verwenden müssen. Wenn Sie es nur in einer Datei benötigen, war es immer in Ordnung, es in die .m-Datei einzufügen.
Dave DeLong

206

Apple bietet ein Makro für eine bessere Codekompatibilität, einschließlich Swift. Die Verwendung des Makros sieht folgendermaßen aus.

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

Hier dokumentiert


Können Obj C-Enums Mitgliedsvariablen haben, wie sie es in Java können? Wenn das so ist, wie?
Uhrmacher

Die zweite Lösung ist also besser?
Iulian Onofrei

3
Die zweite Lösung ist besser (mit NS_ENUM), da sie moderner ist und jetzt in Objective-C erforderlich ist, wenn Ihre Aufzählung in Swift-Code verfügbar sein soll.
Smileyborg

Aktualisiert, um zu zeigen, dass die zweite Lösung tatsächlich besser ist.
Rebellzach

In Apples Standardformular wird der Typname für jeden Aufzählungswert wiederholt.
ThomasW

29

In der .h:

typedef enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
} PlayerState;

1
Sie können eine solche Antwort in anderen SO-Fragen finden, aber als ich die Aufzählungen überprüfte, tauchte diese Frage zuerst auf, sodass ich die Antwort auch hier hinzufügte.
Ben Flynn

19

Bei aktuellen Projekten möchten Sie möglicherweise die Makros NS_ENUM()oder verwenden NS_OPTIONS().

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

2
... und was noch wichtiger ist, Sie müssen Enums mit NS_ENUMObjective-C deklarieren, wenn Ihre Enum im Swift-Code verfügbar sein soll.
Smileyborg

16

So macht es Apple für Klassen wie NSString:

In der Header-Datei:

enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
};

typedef NSInteger PlayerState;

Weitere Informationen finden Sie in den Codierungsrichtlinien unter http://developer.apple.com/.


3
Dies hilft dem OP nicht wirklich. Obwohl es technisch korrekt ist, sagt es ihnen nicht, wie sie eine wiederverwendbare Aufzählung erstellen sollen
RyanR

24
Das Verknüpfen mit developer.apple.com ist nicht wirklich hilfreich. Gibt es einen anderen Ort, den Sie stattdessen zitieren möchten?
Brett

Kopieren / Einfügen Dokumentation, die bereits gegeben hat, der Link, der die Hauptseite ist, hilft wirklich nicht anderen Menschen ...
Onder OZCAN

3
Dies ist jetzt veraltet, siehe diese Seite developer.apple.com/library/ios/releasenotes/ObjectiveC/…
Alex Chesters

8

Ich empfehle die Verwendung von NS_OPTIONS oder NS_ENUM. Weitere Informationen finden Sie hier: http://nshipster.com/ns_enum-ns_options/

Hier ist ein Beispiel aus meinem eigenen Code mit NS_OPTIONS. Ich habe ein Dienstprogramm, das eine Unterebene (CALayer) auf der Ebene einer UIView festlegt, um einen Rahmen zu erstellen.

Die h. Datei:

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

Die .m-Datei:

@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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.