Forward-declare enum in Objective-C
我在Objective-C程序中遇到枚举可见性问题。我有两个头文件,其中一个定义了一个
在纯C语言中,我只简单地将另一个头文件
我不需要实际的枚举值,除非在相应的
最新的方法(Swift 3;2017年5月)在目标C中转发声明枚举(ns-enum/ns-u选项)是使用以下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // 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头文件,或者使用nsinteger之类的通用类型而不是枚举类型。
但是,有更多的理由不导入头文件,而不仅仅是编译速度。
不导入头文件也会减少无意中访问无关类的次数。
例如,假设有一个trackfilechanges类跟踪文件系统对特定文件的更改,并且有一个cachedFile类存储文件中缓存的数据。后者可能使用trackfilechanges*类型的私有ivar,但对于cachedfile的使用,这只是一个实现细节(理想情况下,使用新的运行时,将使用私有属性自动生成ivar,但如果使用旧的运行时间,这是不可能的)。
因此,导入"cachedfile.h"的客户机可能不需要或不希望访问trackfilechanges.h。如果需要,他们应该通过自己导入来明确。通过在cachedfile.h中使用@class trackfilechanges instea of import"trackfilechanges.h",可以改进封装。
但是,尽管如此,如果第二个头文件希望向所有客户机公开第一个头文件,那么从第二个头文件导入头文件并不困难。例如,声明类的头文件需要直接导入到头文件的子类中,而声明协议的头文件也可以直接导入(尽管您可以使用@protocol abc;来避免这种情况)。
继续使用
如果您可以使用编译器扩展,那么可以使用以下命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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) { } |
注:会触发
如果使用C++ 11,则应该使用它们的枚举,这些枚举是安全的向前声明的,例如EDCOX1×6 }(不是编译器扩展)。
在目标c.h文件中,为实现枚举的前向声明而工作的是在projectname swift.h文件中查找并查看它所放置的内容,结果如下:
枚举swiftenumname:nsinteger;
我需要这个forward声明,因为我有一个函数参数类型swiftenumname。它不会让我把项目名swift.h import放在目标c.h文件中。
然后,在目标C.M文件中,我只使用了import"projectname swift.h",并正常使用swiftenum。
使用的是Swift 4.1.2。
不管怎样,您都必须使用
为什么C++不支持枚举的正向声明?