2009-06-18 62 views
17

枚举不允许作为NSMutableDictionary的键吗?typedef枚举类型作为NSDictionary的关键?

当我尝试通过添加到字典:

[self.allControllers setObject:aController forKey:myKeyType]; 

我得到的错误:

error: incompatible type for argument 2 of 'setObject:forKey:'

通常情况下,我使用NSString作为我的键名不要求强制转换为'身份证',但为了让错误消失,我已经这样做了。在这里铸造正确的行为还是枚举作为关键是一个坏主意?

我的枚举定义为:

typedef enum tagMyKeyType 
{ 
    firstItemType = 1, 
    secondItemType = 2 
} MyKeyType; 

和字典的定义,妥善这样分配的:

NSMutableDictionary *allControllers; 

allControllers = [[NSMutableDictionary alloc] init]; 
+0

为什么你不使用数组? – user102008 2011-07-29 23:38:14

回答

21

尽管您可以将枚举存储在NSNumber中。 (不是enums只是整数?)

[allControllers setObject:aController forKey:[NSNumber numberWithInt: firstItemType]]; 

在可可中,常常使用NSString。在.H你会声明是这样的:

NSString * const kMyTagFirstItemType; 
NSString * const kMyTagSecondtItemType; 

而在.m文件,你会把

NSString * const kMyTagFirstItemType = @"kMyTagFirstItemType"; 
NSString * const kMyTagSecondtItemType = @"kMyTagSecondtItemType"; 

然后你可以使用它作为字典中的一个关键。

[allControllers setObject:aController forKey:kMyTagFirstItemType]; 
+2

我想你想在这里的.h文件中使用`extern`关键字,对吗? – 2011-12-15 05:50:00

3

不,你不能。看看方法签名:id指定一个对象。枚举类型是一个标量。你不能从一个人投到另一个人,并期望它能正常工作。你必须使用一个对象。

+5

这是真的。但是,您可以将枚举值包装在NSNumber中并将其用作关键字。 – LBushkin 2009-06-18 18:23:36

4

这是一个老问题,但可以更新为使用更现代的语法。首先,iOS 6中,苹果建议枚举被定义为:

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 S中的枚举,我们可以框它们变成NSNumber s到存储作为字典的关键。

NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 

// set the value 
dictionary[@(MyEnumValue1)] = @"test"; 

// retrieve the value 
NSString *value = dictionary[@(MyEnumValue1)]; 

编辑:如何创建一个单独的字典用于此目的

通过这种方法,您可以创建一个单独的字典,以协助这一点。在你拥有的任何文件上,你可以使用:

static NSDictionary *enumTranslations; 

然后你initviewDidLoad(如果你在一个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)文件。