2012-02-12 8 views
4

Objective-CにJavaスタイルの列挙型が非常に役立つ状況があります。私は一連のレイヤータイプを持っており、各レイヤーにはそれに関連付けられた独自のパーシスタンス値があります(秒単位で保存されます)。 JavaではObjective-CにJava enumのようなものはありますか?

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

、私は簡単にこのようなもので、これらの2つの値を関連付けることもできます:彼らは別々のクラスに作るにはあまりにも似ているので、私はそうのように、列挙型ではこれらの層の種類を維持したい

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

    private int persistence; 

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

Objective-Cでこのような軽量クラスのソートを作成する簡単な方法はありますか、より原始的な方法に頼る必要がありますか?

EDIT:

:私はこのような何か(Javaスタイルの列挙型)を有していてもよいので、これは、私のために動作しません

様々な人々がこのような何かをやって提案しています

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

Javaでは、ほこりと爆発は一意の値として扱われますが、C列挙型を使用した直接割り当てでは、まったく同じものとして処理されます。

+0

int値をenum値として使用しても問題ありません([この回答](http://stackoverflow.com/questions/5785965/is-the-following-syntax-is-correct-for-anを参照) -enum)カスタムenum値の例は?) – perelman

+0

@perelman:うーん、私はその機能を知らなかった。それは間違いなく可能ですが、ちょっとハッキリしています。 –

+0

@perelman:複数のレイヤータイプが同じパーシスタンス値を共有している可能性があるため、ユニークなままでなければならないので、2番目の考えでは、いいえ、できません。 –

答えて

2

あなただけの型と値のための原始的なコンテナをしたい場合は、この方法を検討してください。

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

その後、物事が複雑になったり、より良い動的に処理されている場合は、もう一度、クラス階層は検討する価値があるかもしれません。注意:保存するオブジェクトや作成するオブジェクトがたくさんある場合、objc型は過度の負荷となり、パフォーマンスが低下します。

残念ながら、私のJava-Fuはenumのすべてのlangの違いを知るには不十分です。

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 

使用法:

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

あなたは単にそれらを使用することができます:彼らはint型に過ぎないとして

FXLayerType* aJetLayerType = [FXLayerType jetLayerType]; 
+0

タイプが一意でなければならないので、これは私のためには機能しません。Javaでは、2つの値、 'ExplosionLayerType(3)'と 'DustLayerType(3)'を宣言すると、それらは同じ永続性値を共有しますが、一意のままです。これは同じように扱います。 –

1

実際には、C言語で列挙型のキーに値を割り当てることができの値がFXLayerTypeの変数に割り当てられます。

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

私の別のコメントを引用するには:タイプが一意でなければならないので、これは私のためには機能しません。 Javaでは、2つの値、 'ExplosionLayerType(3)'と 'DustLayerType(3)'を宣言すると、それらは同じ永続性値を共有しますが、一意のままです。これは同じように扱います。 –

2

Javaの列挙型をエミュレートするには、フィールドを持つことができる、同等のもの(オペランドは==など)を必要とし、軽量です。これは、構造体、およびオプションで構造体へのポインタを示唆しています。ここで、後者の例である:

FXLayerType.h:

typedef const struct { int persistence; } FXLayerType; 

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

FXLayerType。M:OBJの-Cのオブジェクトと同様に、我々は常にこれらの構造体へのポインタを使用しながら、

#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自体は、一定の構造体です。実装は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は定数ポインタではなく、列挙型の "リテラル"だけが定数として定義されています。

このように書かれているように、switchをenum値にできないという欠点があります。しかし、それが必要な場合は、たとえばtagという2番目のフィールドを追加し、実際の列挙型を使用して一意の値、たとえば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); 

2つの設計の違い最初は周りに通過しますポインタは第2の構造体を持ち、それは大きくてもよい。それらを組み合わせて、switchのポインタベースの列挙型を得ることができます。これは演習として残されています!

これらの設計の両方とも、列挙型「リテラル」の数をいつでも拡張できるという利点があります。

0

最近j2objc形式をenumに使用しました。むしろうまく機能します。さらに、Javaオブジェクトから直接マップしようとすると、自動的にenumを生成することができます。

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

しかし、私は私の "列挙型" からj2objc特定のクラスを削除しました。私は追加の依存関係は望んでいませんでした。

0

構造体ベースの回答は面白そうですが、Objective-Cオブジェクトを構造体に追加しようとすると失敗します。その制限を考えると、Javaスタイルの列挙型を真にエミュレートすることは、それが価値あるものより多くの仕事になる可能性があります。

関連する問題