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;

}
RexOnRoids
quelle
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.

Dave DeLong
quelle
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

Rebellzach
quelle
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;
Ben Flynn
quelle
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
    };
Sean Woodward
quelle
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/.

Santhos
quelle
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
Johannes
quelle