Program Tip

Objective-C의 정방향 선언 열거

programtip 2020. 11. 15. 11:41
반응형

Objective-C의 정방향 선언 열거


Objective-C 프로그램에서 열거 형 가시성에 문제가 있습니다. 두 개의 헤더 파일이 있고 하나는 typedef enum. 다른 파일은 typedef'd 유형 을 사용해야합니다 .

스트레이트 C에서는 단순히 #include다른 헤더 파일을 사용하지만 Objective-C에서는 필요에 따라 #import포워드 @class선언을 사용하는 대신 헤더 파일간에 사용하지 않는 것이 좋습니다 . 그러나 열거 유형을 전달 선언하는 방법을 알 수 없습니다.

.m안전하게 #import제거 할 수 있는 해당 구현 파일을 제외하고는 실제 열거 된 값이 필요하지 않습니다 . 그렇다면 typedef enum헤더에서를 어떻게 인식 할 수 있습니까?


계속해서 #import. 사람들이 @class가능할 때 사용하도록 권장하는 유일한 이유 는 코드 컴파일 속도가 약간 빨라지기 때문입니다. 그러나 #import하나의 .h 파일을 다른 파일에서 가져 오는 데 문제가 없습니다 . 실제로 다른 클래스를 확장 할 때이 작업을 수행해야합니다.


Objective-c에서 열거 형 (NS_ENUM / NS_OPTION)을 전달하는 가장 최근 방법 (Swift 3, 2017 년 5 월)은 다음을 사용하는 것입니다.

// Forward declaration for XYZCharacterType in other header say XYZCharacter.h
typedef NS_ENUM(NSUInteger, XYZCharacterType);


// Enum declaration header: "XYZEnumType.h"
#ifndef XYZCharacterType_h
#define XYZCharacterType_h

typedef NS_ENUM(NSUInteger, XYZEnumType) {
    XYZCharacterTypeNotSet,
    XYZCharacterTypeAgent,
    XYZCharacterTypeKiller,
};

#endif /* XYZCharacterType_h */`

귀하의 질문에 대한 대답은 계속해서 typedef 헤더 파일을 가져 오거나 enum 유형 대신 NSInteger와 같은 일반 유형을 사용하는 것입니다.

그러나 컴파일 속도보다 헤더 파일을 가져 오지 않는 이유가 더 많습니다.

헤더 파일을 가져 오지 않으면 외부 클래스에 대한 부주의 한 액세스도 줄어 듭니다.

예를 들어, 특정 파일의 변경 사항에 대해 파일 시스템을 추적하는 TrackFileChanges 클래스가 있고 파일에서 캐시 된 데이터를 저장하는 CachedFile 클래스가 있다고 가정합니다. 후자는 TrackFileChanges * 유형의 개인 ivar를 사용할 수 있지만 CachedFile 사용의 경우 이는 단순히 구현 세부 사항입니다 (이상적으로는 ivar가 새 런타임을 사용하여 개인 속성으로 자동 생성되지만 다음과 같은 경우에는 불가능합니다.) 다시 이전 런타임 사용).

따라서 #import "CachedFile.h"를 수행하는 클라이언트는 TrackFileChanges.h에 액세스 할 필요가 없거나 액세스를 원하지 않을 것입니다. 그리고 만약 그렇다면, 그들은 스스로 #importing하여 그것을 명확히해야합니다. CachedFile.h에서 #import "TrackFileChanges.h"의 @class TrackFileChanges instea를 사용하면 캡슐화가 향상됩니다.

그러나 두 번째 헤더가 첫 번째 헤더를 모든 클라이언트에 노출하려는 경우 두 번째 헤더 파일에서 헤더 파일을 가져 오는 데 문제가 없습니다. 예를 들어, 클래스를 선언하는 헤더 파일은 서브 클래 싱 헤더 파일에서 직접 가져와야하며 프로토콜을 선언하는 헤더 파일은 직접 가져 오는 것이 좋습니다 (이를 방지하기 위해 @protocol ABC를 사용할 수 있지만).


컴파일러 확장을 사용해도 괜찮다면 Clang에서 다음 순서를 사용할 수 있습니다.

enum Enum;
typedef enum Enum Enum2;

void f(Enum2); // ok. it sees this type's true name.

enum Enum {
    E_1
};

// ok. now its declaration is visible and we can use it.

void f(Enum2 e) {

}

참고 : -Wpedantic경고 가 발생합니다 .


C ++ 11을 사용하는 enum class Enum:uint8_t;경우에는 (컴파일러 확장이 아닌) 선언을 안전하게 전달할 수있는 열거 형을 사용해야합니다 .


Objective C .h 파일에서 나를 위해 열거 형을 앞으로 선언하는 데 효과가 있었던 것은 ProjectName-Swift.h 파일을보고 무엇을 넣었는지 확인하는 것이 었습니다.

enum SwiftEnumName : NSInteger;

I needed this forward declaration because I had a function parameter type of SwiftEnumName. And it wouldn't let me put the ProjectName-Swift.h import in the Objective C .h file.

Then in the Objective C .m file I just had the #import "ProjectName-Swift.h" in it and just used the SwiftEnum normally.

This was using Swift 4.1.2.


You'd have to either #import them anyway or create a separate header file containing only the typedef. Not importing header files in a header makes the compilation faster, but doesn't change anything else.

Why doesn't C++ support forward declaration of enums?

참고URL : https://stackoverflow.com/questions/946489/forward-declare-enum-in-objective-c

반응형