- キーが
- 値は
NSObject
NSDictionary
のいくつかのサブクラスが(列挙型がNSCopying
に準拠していないここでは動作しませんされている列挙型です辞書/ハッシュマップを作成する必要があります)。
私はおそらくここでCFDictionaryRef
を使用することができますが、これを実現する方法が他にあるかどうかを知りたいと思います。
NSObject
NSDictionary
のいくつかのサブクラスが(列挙型がNSCopying
に準拠していないここでは動作しませんされている列挙型です辞書/ハッシュマップを作成する必要があります)。
私はおそらくここでCFDictionaryRef
を使用することができますが、これを実現する方法が他にあるかどうかを知りたいと思います。
enumsは整数なので、NSNumberに列挙型をラップすることができます。あなたは盗ん/マップから/に何かを追加するときは、するNSNumberコンストラクタに列挙型を渡す...
あなたが列挙型などを持っていると仮定すると...
enum ETest {
FOO, BAR
};
あなたにはそれを使用することができますこのようなNSDictionaryのは...
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject: @"Foo!" forKey:[NSNumber numberWithInt: FOO]];
NSLog(@"getting value for FOO -> %@",
[dict objectForKey: [NSNumber numberWithInt: FOO]]);
[dict release];
enums don't conform to NSCopying
これは控えめな表現です。列挙型はオブジェクトではないので、何にも適合しません。それらは整数と互換性のある基本的なCの値です。それがキーとして使用できないのは、それが本当の理由です。 NSDictionary
のキーと値はオブジェクトである必要があります。しかし列挙型は整数なので、それらをNSNumber
オブジェクトにラップすることができます。これはおそらく最も簡単なオプションです。
列挙型が0から数に連続している場合(つまり、手動で値を設定しなかった場合)は、NSArray
を使用できます。インデックスはキーの列挙型の値を表します。 (いずれも「行方不明」のエントリがNSNull
で満たさなければならない。)VoidPointerの提案で
、列挙型が-fshort-enums
がプレイしているときなど、整数(ではないことが判明したときにそれらの時のためにNSValue
を使用する方であってもよいし、おそらくFoundationとの互換性を失うことはないでしょう)。
NSValue *value = [NSValue value: &myEnum withObjCType: @encode(enum ETest)];
。
現代のコンパイラでは、enums to use a fixed underlying typeと言うことができます。つまり、列挙型に使用するストレージを制御できますが、上記の解決策は一般的なので、これを知っていても適用されます。
ニース、これは確かにNSValueがそこにあるのと同じくらい良いフィット感です。 NSValueはintに指された値をコピーしますか? – VoidPointer
OK、http://cocoadev.com/forums/comments.php?DiscussionID=1169&page=1にコピーがあります:) – VoidPointer
UIKeyboardTypeをNSValueに変換することを提案していますが、エラー:http://stackoverflow.com/questions/6130315/how-to-add-a-method-to-uitextfield-uitextview/6132880#6132880 – ma11hew28
さらにあなたはあなた以外NSObjectのタイプのキーと値を追加することができますNSMutableDictionaryにメソッドを追加するために、Objective-Cのcategoryを使用することができます...グラハム・リーからの提案に
を拡張。これにより、コードはラップ/アンラッピング構文から解放されます。再び
、まず、我々はNSValueにコンストラクタを説得追加している
enum ETest { FOO, BAR };
を仮定:
@interface NSValue (valueWithETest)
+(NSValue*) valueWithETest:(enum ETest)etest;
@end
@implementation NSValue (valueWithETest)
+(NSValue*) valueWithETest:(enum ETest)etest
{
return [NSValue value: &etest withObjCType: @encode(enum ETest)];
}
@end
次へ]を我々はNSMutableDictionary
に@interface NSMutableDictionary (objectForETest)
-(void) setObject:(id)anObject forETest:(enum ETest)key;
-(id) objectForETest:(enum ETest)key;
@end
@implementation NSMutableDictionary (objectForETest)
-(void) setObject:(id)anObject forETest:(enum ETest)key
{
[self setObject: anObject forKey:[NSValue valueWithETest:key]];
}
-(id) objectForETest:(enum ETest)key
{
return [self objectForKey:[NSValue valueWithETest:key]];
}
@end
'を列挙ETEST' サポートを追加します
したがって、元の例は、
0に変換することができます。NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject: @"Bar!" forETest:BAR];
NSLog(@"getting value Bar -> %@", [dict objectForETest: BAR]);
[dict release];
辞書にアクセスするためのenumの使用量によっては、コードの可読性がかなり低下する可能性があります。
です。ピンポン:-)。 +1 NSValueカテゴリの場合、私は個人的にNSMutableDictionaryカテゴリを使用しませんでした。なぜオブジェクトをキーとして渡さなかったのか、私は絶えず疑問に思います。そして、なぜ私は '' [NSDictionary objectForetest:] 'を呼び出せなかったのですか?:/ –
少なくとも、ある種のプリミティブ、つまり' 'オブジェクトクラス ''の型を特定する方法があったらいいのに。それはボクシング/アンボクシングプロセスをより多くの生き生きとさせるだろう。 –
私はカテゴリアプローチも好きで、おそらく私の場合もこれを実装します。新しいリテラル/ボクシングの表現は、それが何であれ、@(FOO)を使用してボクシングの世話をするだろうか?
私はそう思っていますし、そうであれば、それをキーとして使用するときに明示的にボクシングすることによって非常に透過的に動作します。
ありがとうございます!それは絶対にうまくいった:) – PlagueHammer