Pla*_*mer 24 cocoa enums dictionary hashtable objective-c
我需要创建一个字典/ hashmap
NSObjectNSDictionary在这里不会工作(枚举不符合NSCopying).
我也许可以在CFDictionaryRef这里使用,但我想知道是否还有其他方法可以实现这一点.
Voi*_*ter 30
由于枚举是整数,因此可以将枚举包装在NSNumber中.当您向/从地图添加/返回内容时,将枚举传递给NSNumber构造函数...
假设你有一个像...这样的枚举
enum ETest {
FOO, BAR
};
Run Code Online (Sandbox Code Playgroud)
你可以在像这样的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];
Run Code Online (Sandbox Code Playgroud)
小智 28
使用VoidPointer的建议,最好NSValue在枚举结果不是整数的时候使用(例如-fshort-enums在播放时,这应该永远不会因为你可能会破坏与Foundation的兼容性).
NSValue *value = [NSValue value: &myEnum withObjCType: @encode(enum ETest)];
Run Code Online (Sandbox Code Playgroud)
这不会在这里增加很多但是给你一般的"我想在集合类中使用<非ObjC类型的名称>"技术.
请注意,使用现代编译器,您可以告诉枚举使用固定的基础类型.这意味着您可以控制用于枚举的存储空间,但由于上述解决方案是通用的,因此即使您知道这一点,它仍然适用.
进一步扩展Graham Lee的建议......
您可以使用objective-c 类别向NSMutableDictionary添加一个方法,该方法允许您使用非NSObject类型的键添加值.这使您的代码不受包装/解包语法的影响.
再说一次,假设
enum ETest { FOO, BAR };
Run Code Online (Sandbox Code Playgroud)
首先,我们在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
Run Code Online (Sandbox Code Playgroud)
接下来,我们将为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
Run Code Online (Sandbox Code Playgroud)
因此可以将原始示例转换为
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject: @"Bar!" forETest:BAR];
NSLog(@"getting value Bar -> %@", [dict objectForETest: BAR]);
[dict release];
Run Code Online (Sandbox Code Playgroud)
根据您使用枚举访问字典的程度,这可能会使代码的可读性大大降低.
枚举不符合NSCopying
这是轻描淡写; 枚举不会"符合"任何东西,因为它们不是对象; 它们是原始C值,可与整数互换.这就是他们不能用作钥匙的真正原因.NSDictionary需要作为对象的键和值.但由于枚举是整数,你可以将它们包装成NSNumber对象.这可能是最简单的选择.
另一个选项,如果枚举从0到某个数字是连续的(即你没有手动设置任何值),那么你可以使用NSArray索引代表键枚举值的位置.(任何"缺失"的条目都必须填写NSNull.)