typedef枚举类型是NSDictionary的关键?

时间:2009-06-18 18:14:38

标签: objective-c

不允许枚举作为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];

3 个答案:

答案 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;

然后在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)文件中。

答案 2 :(得分:3)

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