Objective-C에서 typedef 열거 형이란 무엇입니까?


1087

나는 그것이 무엇인지 enum, 언제 사용 해야하는지 근본적으로 이해하지 못한다고 생각 합니다.

예를 들면 다음과 같습니다.

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

여기서 실제로 무엇을 선언합니까?


2
사용자 정의 유형이 "enum"입니까? 여러 typedef enum 선언이있는 코드를 발견 할 때까지 내가 생각한 것입니다.
Craig

8
사용자 정의 유형은 ShapeType입니다. typedef에 대해 읽어보십시오 : en.wikipedia.org/wiki/Typedef
rampion

6
Objective-C의 typedef는 C의 typedef와 정확히 동일합니다. Objective-C의 열거 형은 C의 열거 형과 정확히 동일합니다. 이는 3 개의 상수 kCircle = 0, kRectangle = 1 및 kOblateSpheroid = 2, 열거 형에 이름 ShapeType을 지정합니다. "typedef"와 "enum"의 의미를 모르는 경우 C에 관한 책을 구입하십시오.
gnasher729

답변:


1565

익명 열거 형식이 선언 : 세 가지가 여기에 선언되고있는 ShapeType익명 열거에 대한 형식 정의를 선언되고 있으며, 세 개의 이름은 kCircle, kRectanglekOblateSpheroid통합 상수로 선언되고있다.

그것을 분해하자. 가장 간단한 경우 열거 형을 다음과 같이 선언 할 수 있습니다.

enum tagname { ... };

이것은 태그를 사용하여 열거를 선언합니다 tagname. C와 오브젝티브 C (그러나에서 하지 C ++),이에 대한 참조가 있어야합니다 앞에는 enum키워드. 예를 들면 다음과 같습니다.

enum tagname x;  // declare x of type 'enum tagname'
tagname x;  // ERROR in C/Objective-C, OK in C++

enum어디에서나 키워드 를 사용하지 않으려면 typedef를 작성할 수 있습니다.

enum tagname { ... };
typedef enum tagname tagname;  // declare 'tagname' as a typedef for 'enum tagname'

한 줄로 단순화 할 수 있습니다.

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

마지막으로 키워드 enum tagname와 함께 사용할 필요가 없으면 익명을 만들고 typedef 이름으로 만 선언 할 수 있습니다.enumenum

typedef enum { ... } tagname;

이제이 경우 ShapeType익명 열거 형의 typedef 이름으로 선언 됩니다. ShapeType정말 일체형이며, 단 (이며, 하나의 선언에 열거 된 값 중 하나를 보유 변수 선언 표기 kCircle, kRectangle등을 kOblateSpheroid). ShapeType그러나 캐스팅을 통해 변수에 다른 값을 할당 할 수 있으므로 열거 형 값을 읽을 때주의해야합니다.

마지막으로 kCircle, kRectanglekOblateSpheroid글로벌 네임 스페이스에 필수적인 상수로 선언된다. 특정 값이 지정되지 않았으므로 0으로 시작하는 연속 정수에 할당되므로 kCircle0, kRectangle1, kOblateSpheroid2입니다.


6
좋은 설명-한 가지만 추가하면 C의 비슷한 명명 규칙을 따릅니다 (Objective-C에 대해서는 확실하지 않음).
Michael Burr

109
Objective-C는 C의 적절한 상위 집합입니다. C의 모든 C 구조체 이름 지정 규칙은 Objective-C에서도 유효합니다.
sigjuice 2009

대박. C ++ 스타일 열거 형을 사용할 수 있고 열거 형을 쓸 필요가 없습니다. :)
user4951

11
C ++ 스타일 열거 형은 선언 한 파일이 .m이 아닌 .mm 파일 인 경우 사용할 수 있습니다. Objective-C ++는 터무니없이 강력합니다.
케빈 호프만

14
이 답변에 대해 잘 알고 있으면 새로운 NS_ENUM 및 NS_OPTIONS를 살펴볼 가치가 있습니다. 튜토리얼 : nshipster.com/ns_enum-ns_options 및 SO : stackoverflow.com/questions/14080750/…
Snowcrash

254

Apple은 Xcode 4.4 부터 다음과 같은 열거 형을 정의하는 것이 좋습니다 .

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

또한 편리한 매크로를 제공합니다 NS_ENUM.

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

이러한 정의는 더 강력한 유형 검사와 더 나은 코드 완성을 제공합니다. 공식 문서를 찾을 수 없지만 NS_ENUMWWDC 2012 세션의 "Modern Objective-C"비디오를 여기에서 볼 수 있습니다 .


업데이트 여기
공식 문서 링크 .


13
"Enum Improvements"에 대한 부분은 5:58에서 시작
vikingosegundo

5
다른 답변에 대해 언급 한 것처럼 NS_ENUMNSHipster 의 Apple 매크로 설명 : NSHipster.com/ns_enum-ns_options
Basil Bourque

1
이것은 NS_ENUM에 관한 공식 문서에 대한 링크입니다 : developer.apple.com/library/ios/releasenotes/ObjectiveC/…
YoGiN

50

열거 형은 일련의 정렬 된 값을 선언합니다. typedef는 편리한 이름을 추가합니다. 첫 번째 요소는 0 등입니다.

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

WORKDAYS today = Monday;

위는 shapeType 태그의 열거입니다.


34

가능한 값이있는 사용자 정의 형 kCircle, kRectangle또는이 kOblateSpheroid. 열거 형 내부의 값 (kCircle 등)은 열거 형 외부에서 볼 수 있습니다. 이를 명심해야합니다 ( int i = kCircle;예 : 유효).


30

64 비트 변경에 대한 업데이트 : 64 비트 변경 에 대한 Apple 문서 에 따르면 ,

열거 형도 타입 : LLVM 컴파일러에서 열거 형은 열거의 크기를 정의 할 수 있습니다. 즉, 열거 된 일부 유형의 크기가 예상보다 클 수도 있습니다. 다른 모든 경우와 마찬가지로 해결책은 데이터 유형의 크기에 대한 가정을하지 않는 것입니다. 대신 열거 된 값을 적절한 데이터 유형의 변수에 지정하십시오.

따라서 64 비트를 지원하는 경우 아래 구문 과 같은 유형 으로 열거 형만들어야 합니다.

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

또는

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

그렇지 않으면 다음과 같이 경고로 이어집니다. Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType

신속한 프로그래밍을위한 업데이트 :

신속하게 구문이 변경되었습니다.

enum ControlButtonID: NSUInteger {
        case kCircle , kRectangle, kOblateSpheroid
    }

enum 선언 (NS_ENUM)을 전달해야하는 경우 : stackoverflow.com/a/42009056/342794
lal

25

열거 형 (enumeration의 약어)은 값 집합 (열거 기)을 열거하는 데 사용됩니다. 값은 기호 (단어)로 표시되는 추상적 인 것입니다. 예를 들어, 기본 열거 형은

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

이 열거 형은 이름을 지정할 기호가 없으므로 익명이라고합니다. 그러나 여전히 완벽합니다. 그냥 이렇게 사용하세요

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

확인. 인생은 아름답고 모든 것이 잘됩니다. 그러나 언젠가이 열거 형을 재사용하여 myGrandFatherPantSize를 저장할 새 변수를 정의한 후 다음과 같이 작성해야합니다.

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

그러나 컴파일러 오류 "열거의 재정의"가 있습니다. 실제로 문제는 컴파일러가 먼저 열거 형을 확신하지 못하고 두 번째로 동일한 것을 설명한다는 것입니다.

그런 다음 여러 위치에서 동일한 열거 자 집합 (여기서 xs ... xxxxl)을 재사용하려면 고유 한 이름으로 태그를 지정해야합니다. 이 세트를 두 번째로 사용할 때는 태그 만 사용하면됩니다. 그러나이 태그는 열거 형 단어를 대체하는 것이 아니라 열거 자 세트 만 대체한다는 것을 잊지 마십시오. 그런 다음 평소처럼 열거 형을 사용하도록주의하십시오. 이처럼 :

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

매개 변수 정의에서도 사용할 수 있습니다.

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

어디서나 열거 형을 다시 작성하는 것이 편리하지 않으며 코드가 조금 이상하게 보입니다. 네 말이 맞아 실제 유형이 더 좋습니다.

이것이 정상 회담으로 향한 마지막 단계입니다. typedef를 추가하여 열거 형을 실제 유형으로 변환하십시오. 마지막으로, 클래스 내에서 typedef를 사용할 수 없습니다. 그런 다음 바로 위의 유형을 정의하십시오. 다음과 같이하십시오 :

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

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

태그는 선택 사항입니다. 그런 다음이 경우에는 열거 자에 태그를 지정하지 않고 새 유형을 정의하기 만합니다. 그러면 더 이상 필요하지 않습니다.

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

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

XCode를 사용하여 Objective-C에서 개발하는 경우 NS_ENUM 접두사가있는 멋진 매크로를 발견 할 수 있습니다. 그렇게하면 좋은 열거 형을 쉽게 정의 할 수 있으며 정적 분석기가 컴파일하기 전에 흥미로운 검사를 수행하는 데 도움이됩니다.

좋은 열거 형!


나는 항상 "왜 이미 대답하고 받아 들인 질문에 누군가가 대답 할 것"이라고 생각했습니다. 소년, 나는 항상 틀렸다! 이것은 최고의 답변이며 저와 같은 초보자에게 도움이됩니다!
rak appdev

10

typedef기존 변수 유형의 이름을 재정의하는 데 유용합니다. 데이터 유형을 호출하는 짧고 의미있는 방법을 제공합니다. 예 :

typedef unsigned long int TWOWORDS;

여기서 unsigned long int 유형은 TWOWORDS 유형으로 재정의됩니다. 따라서 이제 우리는 unsigned long int 유형의 변수를 작성하여 선언 할 수 있습니다.

TWOWORDS var1, var2;

대신에

unsigned long int var1, var2;

7
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;

다음과 같이 사용할 수 있습니다 :-

 ShapeType shape;

 enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} 
ShapeType;

이제 다음과 같이 사용할 수 있습니다.

enum ShapeType shape;

3

enum은 구조체에서 수행 할 수없는 enum 요소에 값을 할당하는 데 사용됩니다. 따라서 완전한 변수에 액세스하는 대신 열거 형의 변수에 할당 한 값으로 수행 할 수 있습니다. 기본적으로 0 할당으로 시작하지만 값을 할당 할 수 있으며 열거 형의 다음 변수에는 이전 값 +1의 값이 할당됩니다.


3

아래 형식으로 사용할 수 있습니다. 기본 값은 0부터 시작하므로

  • kCircle은 0이며
  • kRectangle은 1이며
  • kOblateSpheroid는 2입니다.

고유 한 시작 값을 지정할 수 있습니다.

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

ShapeType circleShape = kCircle;
NSLog(@"%lu", (unsigned long) circleShape); // prints: 0

2

프로그래머는 typedef를 사용하여 하나의 Objective-C 유형을 다른 것으로 정의 할 수 있습니다. 예를 들어

typedef int 카운터; int 유형과 동등한 Counter 유형을 정의합니다. 이것은 코드 가독성을 크게 향상시킵니다.


2

Typedef는 C 및 C ++의 키워드입니다. 기본 데이터 유형 (char, int, float, double, struct & enum)의 새 이름을 작성하는 데 사용됩니다 .

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

여기에 열거 된 데이터 유형 ShapeType 을 작성 하고 아래에 주어진 것처럼 열거 유형 ShapeType의 새 이름을 작성할 수 있습니다.

ShapeType shape1; 
ShapeType shape2; 
ShapeType shape3;

1

열거 형은 많은 유형의 "오류"를 줄이고 코드를보다 관리하기 쉽게 만듭니다.

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

정의에는 제약이 없습니다. 단순히 대체 일뿐입니다. 상태의 모든 조건을 제한 할 수는 없습니다. STATE가 5로 지정되면 일치하는 상태가 없으므로 프로그램이 잘못됩니다. 그러나 컴파일러는 STATE = 5를 경고하지 않습니다.

이렇게 사용하는 것이 좋습니다

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

SampleState state = SampleStateGood;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.