在符合协议的类中,在Objective-C协议中定义的重新声明/扩展typedef

时间:2010-08-04 10:46:42

标签: iphone c objective-c protocols typedef

我有一个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,以便每个类都可以拥有自己的视图状态。但是,我遇到了以下两个错误:

  1. Redeclaration of enumerator 'ViewStateNone'
  2. Conflicting types for 'ViewState'
  3. 我很惭愧地承认我对C的知识(即typedef s)并不广泛,我在这里尝试做的事情,首先是可能的,其次是明智的吗?

    干杯啦。

2 个答案:

答案 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的可读内容。您还可以在协议中添加另一种方法,该方法将报告实现类支持的值。