Jak zdefiniować i używać ENUM w Objective-C?


180

Zadeklarowałem wyliczenie w moim pliku implementacyjnym, jak pokazano poniżej, i zadeklarowałem zmienną tego typu w moim interfejsie jako PlayerState thePlayerState; i użyłem zmiennej w moich metodach. Ale dostaję błędy stwierdzające, że nie jest to zadeklarowane. Jak poprawnie zadeklarować i użyć zmiennej typu PlayerState w moich metodach:

W pliku .m

@implementation View1Controller

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

w pliku .h:

@interface View1Controller : UIViewController {

    PlayerState thePlayerState;

w jakiejś metodzie w pliku .m:

-(void)doSomethin{

thePlayerState = PLAYER_OFF;

}

2
Teraz typem wyliczenia jestPlayerState. Czym staje się playerStateTypes?
— user4951,

3
Aby uzyskać informacje na temat NS_ENUM i jego najnowszej nowoczesnej składni, zobacz publikację NS_ENUM & NS_OPTIONS autorstwa Mattta Thompsona.
— Basil Bourque

Odpowiedzi:


109

Musisz typedefznajdować się w pliku nagłówkowym (lub innym pliku, który jest #importedytowany w nagłówku), ponieważ w przeciwnym razie kompilator nie będzie wiedział, jaki rozmiar utworzyć PlayerStateivar. Poza tym wydaje mi się to w porządku.


Opcja umieszczenia go w osobnym pliku wydawała mi się odpowiednia w moim przypadku. Nie wiem, czy to jest dobre podejście, ale musiałem użyć tego samego wyliczenia w dwóch różnych ViewControllerach (self i jego delegate / datasource). Importowanie nagłówka delegata / źródła danych spowodowało błąd i wydaje się zbyt duże, by zaspokoić zwykłą potrzebę. Więc stworzyłem nowy plik .h z zadeklarowanym wyliczeniem i zaimportowałem go zarówno do pliku viewControllers.h. Działa jak urok.
— Leandro Alves

7
Powinien zalecić użycie makra NS_ENUM - ponieważ jest to najlepsza praktyka
— khebbie

1
Musisz zadeklarować NS_ENUMwyliczenia za pomocą w Celu-C, jeśli chcesz, aby wyliczenie było dostępne w kodzie Swift.
— smileyborg,

@DaveDeLong, czy to nadal obowiązuje w 2015 roku? Mam typedefzadeklarowany w .mpliku, który kompiluje się i działa dobrze.
— Iulian Onofrei

@IulianOnofrei przejdzie do pliku .h, jeśli będziesz musiał użyć wyliczenia w innych plikach. Jeśli potrzebujesz go tylko w jednym pliku, umieszczenie go w pliku .m zawsze było w porządku.
— Dave DeLong

206

Apple udostępnia makro, które pomaga zapewnić lepszą zgodność kodu, w tym Swift. Korzystanie z makra wygląda następująco.

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

Udokumentowane tutaj


Czy Obj C Enums może mieć zmienne składowe tak jak w Javie? Jeśli tak to jak?
— kowal

Więc drugie rozwiązanie jest lepsze?
— Iulian Onofrei

3
Drugie rozwiązanie jest lepsze (przy użyciu NS_ENUM), ponieważ jest bardziej nowoczesne i jest teraz wymagane w Objective-C, jeśli chcesz, aby twoje wyliczenie było dostępne w kodzie Swift.
— smileyborg,

Zaktualizowano, aby pokazać, że drugie rozwiązanie jest w rzeczywistości lepsze.
— rebelzach

W standardowej formie Apple nazwa typu jest powtarzana dla każdej wartości wyliczeniowej.
— ThomasW,

29

W .h:

typedef enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
} PlayerState;

1
Taką odpowiedź możesz znaleźć w innych pytaniach SO, ale kiedy przeglądałem wyliczenia, pytanie to pojawiło się jako pierwsze, więc tutaj również dodałem odpowiedź.
— Ben Flynn,

19

W przypadku bieżących projektów możesz użyć makra NS_ENUM()lub NS_OPTIONS().

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

2
... i co ważniejsze teraz, musisz zadeklarować NS_ENUMwyliczenia za pomocą w Objective-C, jeśli chcesz, aby wyliczenie było dostępne w kodzie Swift.
— smileyborg,

16

Oto jak Apple robi to dla klas takich jak NSString:

W pliku nagłówkowym:

enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
};

typedef NSInteger PlayerState;

Zobacz Wskazówki dotyczące kodowania na stronie http://developer.apple.com/


3
To nie pomaga OP. Chociaż technicznie poprawne, nie mówi im, jak stworzyć wyliczenie wielokrotnego użytku
— RyanR

24
Linkowanie do developer.apple.com nie jest naprawdę pomocne. Czy jest jeszcze jakieś miejsce, które chciałbyś zacytować?
— Brett,

Skopiuj / wklej dokumentację, która już została podana, link, który jest główną stroną, naprawdę nie pomaga innym ludziom ...
— Onder OZCAN

3
To jest już nieaktualne, zobacz tę stronę developer.apple.com/library/ios/releasenotes/ObjectiveC/…
— Alex Chesters

8

Polecam użycie NS_OPTIONS lub NS_ENUM. Możesz przeczytać więcej na ten temat tutaj: http://nshipster.com/ns_enum-ns_options/

Oto przykład z mojego własnego kodu używającego NS_OPTIONS, mam narzędzie, które ustawia podwarstwę (CALayer) na warstwie UIView w celu utworzenia granicy.

H. plik:

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

Plik .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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.