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

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

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

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

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



답변

익명 열거 형식이 선언 : 세 가지가 여기에 선언되고있는 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입니다.


답변

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”비디오를 여기에서 볼 수 있습니다 .


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


답변

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

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

WORKDAYS today = Monday;

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


답변

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


답변

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
    }


답변

열거 형 (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 접두사가있는 멋진 매크로를 발견 할 수 있습니다. 그렇게하면 좋은 열거 형을 쉽게 정의 할 수 있으며 정적 분석기가 컴파일하기 전에 흥미로운 검사를 수행하는 데 도움이됩니다.

좋은 열거 형!


답변

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

typedef unsigned long int TWOWORDS;

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

TWOWORDS var1, var2;

대신에

unsigned long int var1, var2;