Objective-C中的前向声明枚举
在Objective-C程序中遇到枚举可见性问题。 我有两个头文件,一个定义了一个typedef enum
。 另一个文件需要使用typedef
types。
在直接的C中,我只是简单地包含另一个头文件,但是在Objective-C中,build议不要在头文件之间使用#import
,而@class
根据需要使用forward @class
声明。 但是,我无法弄清楚如何转发 – 声明一个枚举types。
我不需要实际的枚举值,除了在相应的.m
实现文件中,我可以安全地#import
了。 那么我怎样才能得到在头文件中识别typedef enum
?
继续使用#import
。 人们推荐在可能的时候使用@class
的唯一原因是因为它让你的代码稍微快一点来编译。 但是,从#import
另一个.h文件没有问题。 事实上,在扩展另一个课程时,你需要做到这一点。
你的问题的答案是要么继续和导入typedef头文件或使用像NSIntegergenericstypes而不是枚举types。
但是,不仅仅是编译速度,还有更多的理由不导入头文件。
不导入头文件也可以减less无意中访问无关的类。
例如,假设您有一个跟踪文件系统的TrackFileChanges类来更改特定的文件,并且您有一个CachedFile类来存储文件中的caching数据。 后者可能使用TrackFileChanges *types的私有ivar,但是对于CachedFile的使用,这只是一个实现细节(理想情况下,ivar将使用新的运行时自动生成一个私有属性,但这不可能,重新使用旧的运行时间)。
因此,#import“CachedFile.h”的客户端可能不需要或不想访问TrackFileChanges.h。 如果他们这样做,他们应该通过#importing它自己来清楚。 通过在CachedFile.h中使用#import“TrackFileChanges.h”的@class TrackFileChanges instea,可以改进封装。
但是,所有这一切说,从第二个头文件导入一个头文件没有什么不妥,如果第二个头想要公开第一个到所有的客户端。 例如,声明类的头文件需要直接导入子类头文件,而声明协议的头文件可能直接导入(尽pipe你可以使用@protocol ABC来避免这种情况)。
最近的方法(Swift 3; 2017年5月)转发声明枚举(NS_ENUM / NS_OPTION)在objective-c中是使用以下内容:
// 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 */`
如果你可以使用编译器扩展,你可以在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,你应该使用它们的枚举,这是安全的转发declare – 例如enum class Enum:uint8_t;
(不是编译器扩展)。
你不得不#import
他们无论如何或创build一个单独的头文件只包含typedef
。 不在头文件中导入头文件会加快编译速度,但不会改变其他任何东西。
为什么C ++不支持向前声明枚举?