2009-06-18 45 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)文件。