我需要在
中创建一个字典/ hashmapNSObject
NSDictionary
在此不起作用(枚举不符合NSCopying
)。
我或许可以在这里使用CFDictionaryRef
,但我想知道是否还有其他方法可以实现这一点。
答案 0 :(得分:29)
由于枚举是整数,因此可以将枚举包装在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];
答案 1 :(得分:28)
根据VoidPointer的建议,当枚举结果不是整数时(例如NSValue
正在播放时),最好使用-fshort-enums
,这应该永远不会像你一样可能会破坏与基金会的兼容性。)
NSValue *value = [NSValue value: &myEnum withObjCType: @encode(enum ETest)];
这不会在这里增加太多但是给你一般的“我想在收集类中使用<非ObjC类型的名称>”技术。
请注意,使用现代编译器,您可以告诉enums to use a fixed underlying type。这意味着您可以控制用于枚举的存储空间,但由于上述解决方案是通用的,因此即使您知道这一点,它仍然适用。
答案 2 :(得分:9)
进一步延伸Graham Lee的建议......
您可以使用objective-c category向NSMutableDictionary添加一个方法,该方法允许您使用非NSObject类型的键添加值。这可以使您的代码免于包装/解包语法。
再次,假设
enum ETest { FOO, BAR };
首先,我们在NSValue中添加一个conince构造函数:
@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添加'enum ETest'支持
@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
因此可以将原始示例转换为
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject: @"Bar!" forETest:BAR];
NSLog(@"getting value Bar -> %@", [dict objectForETest: BAR]);
[dict release];
根据您使用enum访问字典的程度,这可能会使代码的可读性大大降低。
答案 3 :(得分:7)
枚举不符合NSCopying
这是轻描淡写;枚举不会“符合”任何东西,因为它们不是对象;它们是原始C值,可与整数互换。这就是他们不能用作钥匙的真正原因。 NSDictionary
的键和值必须是对象。但由于枚举是整数,因此您可以将它们包装到NSNumber
个对象中。这可能是最简单的选择。
另一个选项,如果枚举从0到某个数字是连续的(即你没有手动设置任何值),那么你可以使用NSArray
,其中索引代表关键枚举的值。 (任何“缺失”条目都必须填充NSNull
。)
答案 4 :(得分:2)
我也喜欢类别方法,也可能在我的情况下实现这一点。随着新的文字/拳击表达无论它被称为什么,将使用@(FOO)为你照顾拳击?
我认为通过在将枚举用作键时明确地装入枚举,它会非常透明地工作。