2009-07-27 17 views
23

मैं एक शब्दकोश/hashmap जहांकोको: एनम कुंजी के साथ शब्दकोश?

  • कुंजी enums
  • मान रहे हैं बनाने की जरूरत NSObject के कुछ उपवर्ग

NSDictionary यहाँ काम नहीं करेगा (enums NSCopying के अनुरूप नहीं हैं)।

मैं शायद CFDictionaryRef का उपयोग कर सकता हूं, लेकिन मैं यह जानना चाहता हूं कि इसे प्राप्त करने का कोई अन्य तरीका है या नहीं।

उत्तर

29

चूंकि enums पूर्णांक हैं, इसलिए आप एनएसएनंबर में enum लपेट सकते हैं। जब आप जोड़ सकते हैं/कुछ करने के लिए/नक्शे से, आप enum NSNumber निर्माता को पारित ...

मान लें कि आप एक enum की तरह मिल गया है पुनर्प्राप्त ...

enum ETest { 
    FOO, BAR 
}; 

आप में उपयोग कर सकते हैं इस तरह एक NSDictionary ...

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 
[dict setObject: @"Foo!" forKey:[NSNumber numberWithInt: FOO]]; 
NSLog(@"getting value for FOO -> %@", 
     [dict objectForKey: [NSNumber numberWithInt: FOO]]); 
[dict release]; 
+0

धन्यवाद! यह बिल्कुल बढ़िया काम करता है :) – PlagueHammer

7

enums don't conform to NSCopying

यह एक ख़ामोश है, enums कुछ भी करने के लिए "अनुरूप" नहीं है क्योंकि वे वस्तुओं नहीं हैं; वे आदिम सी मान हैं जो पूर्णांक के साथ अंतर-परिवर्तनीय हैं। यही कारण है कि उन्हें चाबियों के रूप में इस्तेमाल नहीं किया जा सकता है। NSDictionary की चाबियाँ और मान वस्तुएं होने की आवश्यकता है। लेकिन चूंकि enums पूर्णांक हैं, आप उन्हें NSNumber ऑब्जेक्ट्स में लपेट सकते हैं। यह शायद सबसे आसान विकल्प है।

एक और विकल्प, यदि enums 0 से कुछ संख्या तक संगत हैं (यानी आपने मैन्युअल रूप से कोई मान निर्धारित नहीं किया है), तो आप NSArray का उपयोग कर सकते हैं जहां सूचकांक कुंजी enum के मान का प्रतिनिधित्व करता है। (कोई "छूटी" प्रविष्टियों NSNull से भरा जा करना होगा।)

28
VoidPointer के सुझाव के साथ

, जब enums बाहर बारी पूर्णांकों (जब -fshort-enums खेलने में है के रूप में इस तरह के होने के लिए नहीं उस समय के लिए NSValue उपयोग करने के लिए बेहतर हो सकता है, जो कभी भी फाउंडेशन के साथ संगतता तोड़ने के रूप में कभी नहीं होना चाहिए)।

NSValue *value = [NSValue value: &myEnum withObjCType: @encode(enum ETest)]; 
उतना यहाँ जोड़ने के लिए नहीं जा रहा है, लेकिन आप सामान्य तकनीक "मैं एक संग्रह वर्ग में गैर ObjC प्रकार > की < नाम का उपयोग करना चाहते" देता है

ध्यान दें कि आधुनिक कंपाइलर्स के साथ आप enums to use a fixed underlying type बता सकते हैं। इसका मतलब यह है कि आप नियंत्रित कर सकते हैं कि एनम के लिए किस भंडारण का उपयोग किया जाता है, लेकिन उपर्युक्त समाधान सामान्य है क्योंकि यह तब भी लागू होता है जब आप इसे जानते हैं।

+0

अच्छा, यह वास्तव में एक बेहतर फिट है क्योंकि यह वही है जो NSValue के लिए है। क्या NSValue ctor int को इंगित मूल्य की प्रतिलिपि बनाता है? – VoidPointer

+0

ठीक है, http://cocoadev.com/forums/comments.php?DiscussionID=1169&page=1 कहता है कि यह एक प्रतिलिपि बनाता है :) – VoidPointer

+0

मैं UIKeyboardType को 'NSValue' में बदलने के लिए सुझाव देता हूं, लेकिन मुझे मिल रहा है एक त्रुटि: http://stackoverflow.com/questions/6130315/how-to-add-a-method-to-uitextfield-uitextview/6132880#6132880 – ma11hew28

9

इसके अलावा ग्राहम ली से सुझाव पर विस्तार ...

आप NSMutableDictionary के लिए एक विधि आप अपने गैर NSObject प्रकार की एक प्रमुख के साथ एक मूल्य जोड़ने की अनुमति देता है कि जोड़ने के लिए एक उद्देश्य-सी category इस्तेमाल कर सकते हैं । यह आपके कोड को रैपिंग/अनैपिंग सिंटैक्स से मुक्त रखता है।

फिर, यह सोचते हैं

enum ETest { FOO, BAR }; 

सबसे पहले, हम NSValue को एक निर्माता को समझाने जोड़ रहे हैं:

@interface NSValue (valueWithETest) 
+(NSValue*) valueWithETest:(enum ETest)etest; 
@end 

@implementation NSValue (valueWithETest) 
+(NSValue*) valueWithETest:(enum ETest)etest 
{ 
    return [NSValue value: &etest withObjCType: @encode(enum ETest)]; 
} 
@end 

अगला हम NSMutableDictionary

को
@interface NSMutableDictionary (objectForETest) 
-(void) setObject:(id)anObject forETest:(enum ETest)key; 
-(id) objectForETest:(enum ETest)key; 
@end 

@implementation NSMutableDictionary (objectForETest) 
-(void) setObject:(id)anObject forETest:(enum ETest)key 
{ 
    [self setObject: anObject forKey:[NSValue valueWithETest:key]]; 
} 
-(id) objectForETest:(enum ETest)key 
{ 
    return [self objectForKey:[NSValue valueWithETest:key]]; 
} 
@end 
'enum ETest' समर्थन जोड़ देंगे

मूल उदाहरण इस प्रकार

0 में परिवर्तित किया जा सकता है
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 
[dict setObject: @"Bar!" forETest:BAR]; 
NSLog(@"getting value Bar -> %@", [dict objectForETest: BAR]);  
[dict release]; 

इस बात पर निर्भर करते हुए कि आप शब्दकोश को एक्सेस करने के लिए अपने enum का कितना उपयोग करते हैं, यह आपके कोड की काफी आसानी से आसानी से हो सकता है।

+0

उत्तर पिंग-पोंग को रोकने के लिए समय :-)। NSValue श्रेणी के लिए +1, मैं व्यक्तिगत रूप से NSMutableDictionary श्रेणी का उपयोग नहीं करता। मैं लगातार सोच रहा हूं कि मैंने ऑब्जेक्ट को कुंजी के रूप में क्यों नहीं पारित किया। और मैं '- [NSDictionary ऑब्जेक्टफॉरटेस्ट:]': -/ –

+0

क्यों नहीं कह सकता था कि मेरी इच्छा है कि कुछ/किसी भी आदिम, "ला" [ऑब्जेक्ट क्लास] 'के "प्रकार" की पहचान करने के लिए कम से कम एक तरीका था। यह मुक्केबाजी/अनबॉक्सिंग प्रक्रिया को बहुत अधिक जीवित बना देगा। –

2

मुझे श्रेणी दृष्टिकोण भी पसंद है और शायद यह मेरे मामले में भी लागू होगा। नए साहित्य/मुक्केबाजी अभिव्यक्तियों के साथ जो कुछ भी कहा जाता है, क्या @ (फू) का उपयोग आपके लिए मुक्केबाजी का ख्याल रखेगा?

मुझे लगता है कि यह ऐसा होगा और यदि यह कुंजी के रूप में उपयोग करते समय स्पष्ट रूप से मुक्केबाजी के द्वारा बहुत पारदर्शी रूप से काम करता है।

संबंधित मुद्दे