我有一个Objective-C协议:
typedef enum {
ViewStateNone
} ViewState;
@protocol ViewStateable
- (void)initViewState:(ViewState)viewState;
- (void)setViewState:(ViewState)viewState;
@end
我在以下课程中使用此协议:
#import "ViewStateable.h"
typedef enum {
ViewStateNone,
ViewStateSummary,
ViewStateContact,
ViewStateLocation
} ViewState;
@interface ViewController : UIViewController <ViewStateable> {
}
@end
我不会对我的应用程序的细节进行太深入的研究,但我在这里做的是typedef
在协议中的枚举,以便协议的方法可以获取该类型的输入值。
然后我希望在符合该协议的类中重新声明或扩展该typedef,以便每个类都可以拥有自己的视图状态。但是,我遇到了以下两个错误:
Redeclaration of enumerator 'ViewStateNone'
Conflicting types for 'ViewState'
我很惭愧地承认我对C的知识(即typedef
s)并不广泛,我在这里尝试做的事情,首先是可能的,其次是明智的吗?
干杯啦。
答案 0 :(得分:7)
既不可能也不明智。这来自typedef和enums 基本上只是定义的事实。 (嗯,不是真的,但为了这个目的,他们是。)如果你需要做这样的事情,你可能想要检查你的设计(见下文)。
更多信息
typedef type newtype;
(差不多)等同于
#define newtype type;
和
enum {
ViewStateNone
};
与
基本相同#define ViewStateNone 1
关于两者之间的差异,有一些更精细的要点,使用枚举和typedef的最引人注目的论点当然是整数常量的编译时检查。
然而;一旦看到typedef enum {} type;
,就不会看不到它,一旦看到它,它的名字就是为它而保留的,而且只有它。
有很多方法可以解决这个问题。但这些是很少走过的路径,而且通常是有充分理由的。它很快变得非常难以管理。
作为一种解决方案,您可能希望创建一个新类MyViewState
,它代表一个视图状态和相关信息,它可以很容易地成为NSInteger
的包装。
结束时:检查您的设计。我担心你可能会做一些过于复杂的事情。
答案 1 :(得分:1)
由于错误相当简洁地解释的原因,你当然不可能以它的形式出现。枚举常量只能在任何范围内声明一次,类似于typedef。
此外,在协议中定义类型会有一些概念上的困难,然后实现者可以重新定义。实现者应该符合类型,而不是添加它。如果类需要能够确定自己的一组值,那么协议必须使用足够通用的类型来保存所有可能需要的类型。在这种情况下,您可以使用int
,或者可能更明智地使用类似NSString
的可读内容。您还可以在协议中添加另一种方法,该方法将报告实现类支持的值。