不允许枚举作为NSMutableDictionary的键吗?
当我尝试通过以下方式添加到词典时:
[self.allControllers setObject:aController forKey:myKeyType];
我收到错误:
错误:参数的类型不兼容 2''setObject:forKey:'
通常,我使用NSString作为我的密钥名称,不需要强制转换为'id'但是为了使错误消失,我已经这样做了。铸造在这里是正确的行为还是枚举作为关键是一个坏主意?
我的枚举定义为:
typedef enum tagMyKeyType
{
firstItemType = 1,
secondItemType = 2
} MyKeyType;
字典已定义并正确分配:
NSMutableDictionary *allControllers;
allControllers = [[NSMutableDictionary alloc] init];
答案 0 :(得分:21)
您可以将枚举存储在NSNumber中。 (不是枚举只是整数?)
[allControllers setObject:aController forKey:[NSNumber numberWithInt: firstItemType]];
在Cocoa中,经常使用const NSStrings。在.h中你会声明如下:
NSString * const kMyTagFirstItemType;
NSString * const kMyTagSecondtItemType;
在.m文件中你会放
NSString * const kMyTagFirstItemType = @"kMyTagFirstItemType";
NSString * const kMyTagSecondtItemType = @"kMyTagSecondtItemType";
然后你可以将它用作字典中的一个键。
[allControllers setObject:aController forKey:kMyTagFirstItemType];
答案 1 :(得分:4)
这是一个老问题,但可以更新以使用更现代的语法。首先,从iOS 6开始,Apple建议将枚举定义为:
typedef NS_ENUM(NSInteger, MyEnum) {
MyEnumValue1 = -1, // default is 0
MyEnumValue2, // = 0 Because the last value is -1, this auto-increments to 0
MyEnumValue3 // which means, this is 1
};
然后,由于我们在内部将枚举表示为NSInteger
,因此我们可以将它们装入NSNumber
以存储为字典的键。
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
// set the value
dictionary[@(MyEnumValue1)] = @"test";
// retrieve the value
NSString *value = dictionary[@(MyEnumValue1)];
编辑:如何为此目的创建单例字典
通过此方法,您可以创建单例字典来协助解决此问题。在您拥有的任何文件的顶部,您可以使用:
static NSDictionary *enumTranslations;
然后在init
或viewDidLoad
中(如果您在UI控制器中执行此操作),您可以执行以下操作:
static dispatch_once_t onceToken;
// this, in combination with the token above,
// will ensure that the block is only invoked once
dispatch_async(&onceToken, ^{
enumTranslations = @{
@(MyEnumValue1): @"test1",
@(MyEnumValue2): @"test2"
// and so on
};
});
// alternatively, you can do this as well
static dispatch_once_t onceToken;
// this, in combination with the token above,
// will ensure that the block is only invoked once
dispatch_async(&onceToken, ^{
NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
mutableDict[@(MyEnumValue1)] = @"test1";
mutableDict[@(MyEnumValue2)] = @"test2";
// and so on
enumTranslations = mutableDict;
});
如果您希望外部可以看到此字典,请将静态声明移动到标题(.h
)文件中。
答案 2 :(得分:3)
id
指定一个对象。枚举类型是标量。你不能从一个投射到另一个并期望它正常工作。你必须使用一个对象。