Co to jest typedef enum w Objective-C?

Nie sądzę, że zasadniczo rozumiem, co to jest enum i kiedy go używać.

Na przykład:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

Co tak naprawdę jest tutaj deklarowane?

Author: Team Upvote, 2009-04-02

14 answers

Deklarowane są trzy rzeczy: deklarowany jest anonimowy typ wyliczeniowy, ShapeType deklarowany jest typedef dla tego anonimowego wyliczenia, a trzy nazwy kCircle, kRectangle, i kOblateSpheroid są deklarowane jako stałe całkowe.

Wyjaśnijmy to sobie. W najprostszym przypadku wyliczenie może być zadeklarowane jako

enum tagname { ... };

To deklaruje wyliczenie z tagiem tagname. W C i Objective-C (ale nie C++) wszelkie odniesienia do tego muszą być poprzedzone słowem kluczowym enum. Na przykład:

enum tagname x;  // declare x of type 'enum tagname'
tagname x;  // ERROR in C/Objective-C, OK in C++
Aby uniknąć konieczności używania wszędzie słowa kluczowego enum, można utworzyć typedef:
enum tagname { ... };
typedef enum tagname tagname;  // declare 'tagname' as a typedef for 'enum tagname'

Można to uprościć do jednej linii:

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

I wreszcie, jeśli nie musimy być w stanie używać enum tagname ze słowem kluczowym enum, możemy uczynić enum anonimowym i zadeklarować go tylko nazwą typedef:

typedef enum { ... } tagname;

Teraz, w tym przypadku, deklarujemy ShapeType BYĆ wpisanym imieniem anonimowego wyliczenie. ShapeType jest tak naprawdę tylko typem integral i powinien być używany tylko do deklarowania zmiennych, które zawierają jedną z wartości wymienionych w deklaracji (czyli jedną z kCircle, kRectangle, i kOblateSpheroid). Możesz jednak przypisać ShapeType zmiennej inną wartość, odlewając, więc musisz być ostrożny podczas czytania wartości enum.

Wreszcie, kCircle, kRectangle, i kOblateSpheroid są deklarowane jako stałe całkowe w globalnej przestrzeni nazw. Ponieważ nie podano żadnych konkretnych wartości, zostają one przypisane do kolejnych liczby całkowite zaczynające się od 0, więc kCircle to 0, kRectangle to 1, A kOblateSpheroid to 2.

 1535
Author: Adam Rosenfield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-22 00:19:46

Apple zaleca definiowanie takich enum od Xcode 4.4:

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

Zapewniają również przydatne makro NS_ENUM:

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

Te definicje zapewniają lepsze sprawdzanie typu i lepsze wypełnianie kodu. Nie udało mi się znaleźć oficjalnej dokumentacji NS_ENUM, ale możecie obejrzeć film "Modern Objective-C" z sesji WWDC 2012 tutaj.

Aktualizacja: Link do oficjalnej dokumentacji tutaj .

 242
Author: Vladimir Grigorov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-24 19:07:03

Enum deklaruje zbiór uporządkowanych wartości - typedef dodaje do tego przydatną nazwę. Pierwszy element to 0 itd.

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

WORKDAYS today = Monday;

Powyższe jest tylko wyliczeniem tagów shapeType.

 47
Author: hburde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-20 12:23:47

Typ zdefiniowany przez użytkownika, który ma Możliwe wartości kCircle, kRectangle, lub kOblateSpheroid. Wartości wewnątrz enum (kCircle, itd.) są jednak widoczne poza enum. Ważne jest, aby mieć to na uwadze ({[3] } jest ważne, na przykład).

 34
Author: Brian Mitchell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-01 10:38:08

Update for 64-bit Change: Według Apple docs o 64-bitowych zmianach,

Wyliczenia są również typowane : w kompilatorze LLVM typy wyliczeniowe mogą określ rozmiar wyliczenia. Oznacza to, że niektóre z wymienionych typy mogą również mieć rozmiar większy niż się spodziewasz. Na rozwiązaniem, podobnie jak we wszystkich innych przypadkach, jest brak założeń co do Rozmiar typu danych. Zamiast tego Przypisz dowolne wyliczone wartości do zmiennej z odpowiednimi danymi Typ

Więc musisz utworzyć enum z typem Jak Poniżej składni, jeśli obsługujesz 64-bit.

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

Lub

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

W przeciwnym razie będzie to prowadzić do ostrzeżenia jako Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType

Aktualizacja dla swift-programowanie:

W języku swift następuje zmiana składni.

enum ControlButtonID: NSUInteger {
        case kCircle , kRectangle, kOblateSpheroid
    }
 28
Author: Mani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-06 06:20:00

Enum jest typem danych zdefiniowanym przez użytkownika. WYLICZONE TYPY DANYCH Wyliczone zmienne typu danych mogą przyjmować tylko wartości, które zostały wcześniej zadeklarowane.

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

this_month = feb;

W powyższej deklaracji miesiąc jest zadeklarowany jako wyliczony typ danych. Składa się z zestawu wartości, od stycznia do grudnia. Numerycznie jan otrzymuje wartość 1, feb wartość 2 i tak dalej.

Zmienna this_month jest zadeklarowana jako tego samego typu co month, a następnie zostanie przypisana wartość powiązana z feb. This_month nie można przypisać żadnych wartości poza tymi podanymi na liście inicjalizacyjnej deklaracji miesiąca.

 25
Author: annu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-17 12:13:55

Enum (skrót od enumeration) jest używany do wyliczenia zbioru wartości (enumeratorów). Wartość to dowolna abstrakcyjna rzecz reprezentowana przez symbol (słowo). Na przykład podstawowym enum może być

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

To wyliczenie nazywa się anonimowe, ponieważ nie masz symbolu, aby je nazwać. Ale to nadal jest całkowicie poprawne. Po prostu użyj go w ten sposób

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
Ok. Życie jest piękne i wszystko idzie dobrze. Ale pewnego dnia musisz ponownie użyć tego enum, aby zdefiniować nową zmienną do przechowywania myGrandFatherPantSize, wtedy piszesz:
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandFatherPantSize;

Ale wtedy masz błąd kompilatora "redefinicja enumerator". Właściwie problem polega na tym, że kompilator nie jest pewien, że najpierw wyliczysz, a drugi opisz to samo.

Następnie, jeśli chcesz ponownie użyć tego samego zestawu enumeratorów (tutaj xs...xxxxl) w kilku miejscach należy oznaczyć go unikalną nazwą. Przy drugim użyciu tego zestawu wystarczy użyć znacznika. Ale nie zapominaj, że ten znacznik nie zastępuje słowa enum ale tylko zestaw wyliczeń. Następnie należy zachować ostrożność, aby stosować lek enum jak zwykle. Tak:

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

Możesz użyć go również w definicji parametru:

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

Można powiedzieć, że przepisywanie enum wszędzie nie jest wygodne i sprawia, że kod wygląda trochę dziwnie. Masz rację. Prawdziwy typ byłby lepszy.

Jest to ostatni krok naszego wielkiego postępu na szczyt. Wystarczy dodać typedef przekształćmy nasze enum w prawdziwy typ. AHA ostatnia rzecz, typedef nie jest dozwolony w twojej klasie. Następnie zdefiniuj swój typ tuż powyżej. Zrób to tak:
// enum definition
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl };
typedef enum sizes size_type

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

Pamiętaj, że znacznik jest opcjonalny. W takim przypadku nie oznaczamy enumeratorów, ale po prostu definiujemy nowy typ. Więc już go nie potrzebujemy.

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

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

Jeśli rozwijasz się w ObjectiveC z XCode, pozwolę ci odkryć kilka ładnych makr poprzedzonych ns_enum. To powinno pomóc ci łatwo zdefiniować dobre liczby, a ponadto pomoże analizatorowi statycznemu zrobić kilka interesujących rzeczy sprawdza przed kompilacją.

Dobry Enum !

 23
Author: Vincent Zgueb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-10 18:23:21

typedef jest przydatny do ponownego zdefiniowania nazwy istniejącego typu zmiennej. Zapewnia krótki i znaczący sposób wywołania typu danych. e. g:

typedef unsigned long int TWOWORDS;

Tutaj Typ unsigned long int jest redefiniowany jako typ TWOWORDS. W ten sposób możemy teraz zadeklarować zmienne typu unsigned long int pisząc,

TWOWORDS var1, var2;

Zamiast

unsigned long int var1, var2;
 10
Author: Rajneesh071,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-18 06:03:00
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;

Wtedy możesz go użyć w następujący sposób: -

 ShapeType shape;

I

 enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} 
ShapeType;

Teraz możesz go używać w następujący sposób: -

enum ShapeType shape;
 7
Author: Vivek Sehrawat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-19 07:42:56

Enum służy do przypisania wartości do elementów enum, których nie można wykonać w struct. Więc za każdym razem zamiast dostępu do pełnej zmiennej możemy to zrobić przez wartość, którą przypisujemy do zmiennych w enum. Domyślnie zaczyna się od przypisania 0, ale możemy przypisać dowolną wartość i następnej zmiennej w enum zostanie przypisana wartość poprzednia wartość +1.

 4
Author: Priyanka Naik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-16 12:45:55

Typedef pozwala programiście zdefiniować jeden typ Objective-C jako drugi. Na przykład,

Typedef Int Counter; definiuje licznik typu jako odpowiednik typu int. Znacznie poprawia to czytelność kodu.

 2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-27 22:42:40

Typedef jest słowem kluczowym w C i C++. Jest on używany do tworzenia nowych nazw dla podstawowych typów danych (char, int, float, double, struct & enum).

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

Tutaj tworzy on wyliczony typ danych ShapeType i możemy napisać nowe nazwy dla typu enum ShapeType Jak podano poniżej

ShapeType shape1; 
ShapeType shape2; 
ShapeType shape3;
 2
Author: Yogeesh H T,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-16 12:33:54

Możesz użyć w poniższym formacie, domyślna wartość raw zaczynając od 0, więc

  • kCircle to 0,
  • kRectangle jest 1,
  • kOblateSpheroid jest 2.

Możesz przypisać własną określoną wartość początkową.

typedef enum : NSUInteger {
    kCircle, // for your value; kCircle = 5, ...
    kRectangle,
    kOblateSpheroid
} ShapeType;

ShapeType circleShape = kCircle;
NSLog(@"%lu", (unsigned long) circleShape); // prints: 0
 2
Author: Bilal Arslan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-30 09:41:17

Enum może zmniejszyć wiele rodzajów "błędów" i sprawić, że kod będzie łatwiejszy w zarządzaniu

#define STATE_GOOD 0
#define STATE_BAD 1
#define STATE_OTHER 2
int STATE = STATE_OTHER

Definicja nie ma ograniczeń. To tylko substytucja. Nie jest w stanie ograniczyć wszystkich warunków Państwa. Gdy stan jest przypisany do 5, program będzie źle, ponieważ nie ma pasującego stanu. Ale kompilator nie będzie ostrzegał STATE = 5

Więc lepiej używać w ten sposób

typedef enum SampleState {
    SampleStateGood  = 0,
    SampleStateBad,
    SampleStateOther
} SampleState;

SampleState state = SampleStateGood;
 0
Author: Marcus Thornton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-21 06:29:25