typedef枚举类型是NSDictionary的关键?

Rob*_*son 17 objective-c

枚举不允许作为NSMutableDictionary的键吗?

当我尝试通过以下方式添加到字典:

[self.allControllers setObject:aController forKey:myKeyType];
Run Code Online (Sandbox Code Playgroud)

我收到错误:

错误:'setObject:forKey:'的参数2的不兼容类型

通常情况下,我使用NSString作为我的密钥名称,不需要强制转换为'id',但为了使错误消失,我已经这样做了.演员阵容在这里是正确的行为还是枚举作为关键是一个坏主意?

我的枚举定义为:

typedef enum tagMyKeyType
{
  firstItemType = 1,
  secondItemType = 2
} MyKeyType;
Run Code Online (Sandbox Code Playgroud)

并且字典被定义并正确分配如下:

NSMutableDictionary *allControllers;

allControllers = [[NSMutableDictionary alloc] init];
Run Code Online (Sandbox Code Playgroud)

Bri*_*ell 21

您可以将枚举存储在NSNumber中.(不是枚举只是整数?)

[allControllers setObject:aController forKey:[NSNumber numberWithInt: firstItemType]];
Run Code Online (Sandbox Code Playgroud)

在Cocoa中,经常使用const NSStrings.在.h中你会声明如下:

NSString * const kMyTagFirstItemType;
NSString * const kMyTagSecondtItemType;
Run Code Online (Sandbox Code Playgroud)

在.m文件中你会放

NSString * const kMyTagFirstItemType = @"kMyTagFirstItemType";
NSString * const kMyTagSecondtItemType = @"kMyTagSecondtItemType";
Run Code Online (Sandbox Code Playgroud)

然后,您可以将其用作字典中的键.

[allControllers setObject:aController forKey:kMyTagFirstItemType];
Run Code Online (Sandbox Code Playgroud)

  • 我想你想在.h文件中使用`extern`关键字,对吗? (2认同)

mik*_*eho 5

这是一个老问题,但可以更新以使用更现代的语法。首先,从 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
};
Run Code Online (Sandbox Code Playgroud)

然后,由于我们在内部将枚举表示为NSIntegers,因此我们可以将它们装箱到NSNumbers 中以存储为字典的键。

NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];

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

// retrieve the value
NSString *value = dictionary[@(MyEnumValue1)];
Run Code Online (Sandbox Code Playgroud)

编辑:如何为此目的创建单例字典

通过这种方法,您可以创建一个单例字典来协助完成此操作。在您拥有的任何文件的顶部,您可以使用:

static NSDictionary *enumTranslations;
Run Code Online (Sandbox Code Playgroud)

然后在您的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;
});
Run Code Online (Sandbox Code Playgroud)

如果您希望该字典在外部可见,请将静态声明移至头.h文件 ( )。