Objective-C中有类似Java枚举的东西吗?

时间:2012-02-12 06:52:07

标签: objective-c enums

我有一个Objective-C的情况,其中Java风格的枚举将非常有用。我有一组图层类型,每个图层都有自己的持久性值(以秒为单位存储)。我想将这些图层类型保存在枚举中,因为它们太相似而不能分成单独的类,如下所示:

typedef enum {
    ExplosionLayerType,
    FireworkLayerType,
    FireLayerType,
    FireJetLayerType
} FXLayerType;

在Java中,我可以轻松地将这两个值与以下内容相关联:

public enum FXLayerType {
    Explosion(3),
    Firework(6),
    Fire(7),
    FireJet(-1);

    private int persistence;

    FXLayerType(int persistence) {
        this.persistence = persistence;
    }
}

是否有一种简单的方法可以在Objective-C中创建这样的轻量级类,或者需要采用更原始的方法?

编辑:

各种各样的人建议做这样的事情:

typedef enum {
    ExplosionLayerType = 3,
    FireworkLayerType = 6
} FXLayerType;

这对我不起作用,因为我可能有这样的东西(Java风格的枚举):

Explosion(3),
Firework(6),
Dust(3);

在Java中,Dust和Explosion将被视为唯一值,但使用C枚举直接赋值将视为完全相同。

6 个答案:

答案 0 :(得分:2)

如果您只想要一个类型和值的原始容器,请考虑以下方法:

typedef struct FXLayerValue {
  FXLayerType type;
  int value;
} FXLayerValue;

然后,如果事情变得复杂或者更好地动态处理,那么类层次结构可能是值得考虑的。警告:如果您有大量要保存和/或创建的对象,则objc类型将过度杀伤并降低性能。

不幸的是,我的Java-Fu不足以了解枚举的所有差异。

答案 1 :(得分:2)

为了模拟Java枚举,我们需要一些可比较的东西(可以是==等的操作数),它们可以有字段,并且是轻量级的。这表明结构,以及可选的结构指针。以下是后者的一个例子:

FXLayerType.h:

typedef const struct { int persistence; } FXLayerType;

extern FXLayerType * const LayerTypeExplosion;
extern FXLayerType * const LayerTypeFirework;
extern FXLayerType * const LayerTypeDust;

FXLayerType.m:

#import "FXLayerType.h"

const FXLayerType _LayerTypeExplosion = { 3 };
const FXLayerType _LayerTypeFirework = { 6 };
const FXLayerType _LayerTypeDust = { 3 };

FXLayerType * const LayerTypeExplosion = &_LayerTypeExplosion;
FXLayerType * const LayerTypeFirework = &_LayerTypeFirework;
FXLayerType * const LayerTypeDust = &_LayerTypeDust;

所以FXLayerType本身是一个常量结构,而与Obj-C对象一样,我们总是使用指向这些结构的指针。该实现创建了3个常量结构和3个常量指针。

我们现在可以编写如下代码:

FXLayerType *a, *b;
a = LayerTypeDust;
b = LayerTypeExplosion;

NSLog(@"%d, %d\n", a == b, a->persistence == b->persistence);

哪个输出“0,1” - ab是不同的枚举(0)但具有相同的持久性(1)。请注意ab不是常量指针,只有枚举“literals”被定义为常量。

如上所述,这样做有一个缺点,就是你不能switch枚举值。但是,如果需要,只需添加第二个字段,例如tag,并使用真实枚举使用唯一值初始化它,例如FXLayerStyleTag。如果您愿意总是比较标记(例如a.tag == b.tag`),也可以删除间接。这给你:

FXLayerType.h:

typedef enum { ExplosionTag, FireworkTag, DustTag } FXLayerTypeTag;
typedef struct { FXLayerTypeTag tag; int persistence; } FXLayerType;

extern const FXLayerType LayerTypeExplosion;
extern const FXLayerType LayerTypeFirework;
extern const FXLayerType LayerTypeDust;

FXLayerType.m:

#import "FXLayerType.h"

const FXLayerType LayerTypeExplosion = { ExplosionTag, 3 };
const FXLayerType LayerTypeFirework = { FireworkTag, 6 };
const FXLayerType LayerTypeDust = { DustTag, 3 };

使用:

FXLayerType a, b;
a = LayerTypeDust;
b = LayerTypeExplosion;

NSLog(@"%d, %d\n", a.tag == b.tag, a.persistence == b.persistence);

两种设计之间的差异是第一次绕过指针,而第二种结构可能更大。你可以将它们组合起来,以获得switch能够基于指针的枚举 - 这是一个练习!

这两种设计都具有(dis)优势,可以随时扩展枚举“文字”的数量。

答案 2 :(得分:1)

实际上你可以为C中的枚举键赋值,因为它们只是整数:

typedef enum {
  LayerTypeExplosion = 3,
  LayerTypeFirework = 6,
  LayerTypeFire = 7,
  LayerTypeFireJet = -1
} FXLayerType;

您可以将它们用作限制集值,并将其分配给FXLayerType类型的变量。

FXLayerType myLayerType = LayerTypeFirework;
NSLog(@"Value of myLayerType = %i", myLayerType);
// =>  "Value of myLayerType = 6"

答案 3 :(得分:0)

这不是100%等效,但这可能是您可以在Objective-C中采用的方法。基本上,创建几个类级别的便捷方法来构建FXLayerType的各种配置。

@interface FXLayerType
{
@private
int persistence;
}

+ (FXLayerType*)fireworkLayerType;
+ (FXLayerType*)explosionLayerType;
+ (FXLayerType*)jetLayerType;

@end

@implementation FXLayerType

+ (FXLayerType*)explosionLayerTypeWithPersistence:(int)persistence
{
   FXLayerType* layerType = [[FXLayerType new] autorelease];
   layerType->persistence = persistence;
   return layerType;
}

+ (FXLayerType*)explosionLayerType
{
   return [self explosionLayerTypeWithPersistence:3];
}

+ (FXLayerType*)fireworkLayerType
{
   return [self explosionLayerTypeWithPersistence:6];
}

+ (FXLayerType*)jetLayerType
{
   return [self explosionLayerTypeWithPersistence:-1];
}

@end

用法:

FXLayerType* aJetLayerType = [FXLayerType jetLayerType];

答案 4 :(得分:0)

我最近将j2objc格式用于枚举。它运作得相当不错。此外,如果您尝试直接从Java对象映射,则可以自动生成枚举。

https://code.google.com/p/j2objc/wiki/Enums

但是,我确实从我的“Enums”中删除了j2objc特定的类。我不想要额外的依赖项。

答案 5 :(得分:0)

基于结构的答案看起来很好,但是当你尝试将Objective-C对象添加到结构中时会失败。鉴于这种限制,真正模仿Java风格的枚举可能比它的价值更多。