2008-12-02 16 views
6

मैं किसी विशेष दृष्टिकोण पर कुछ प्रतिक्रिया की सराहना करता हूं जिसे मैं उपयोग करने के बारे में सोच रहा हूं। परिदृश्य नीचे है।कोको में केस-असंवेदनशील केवीसी?

मैं एक वस्तु है गुण, कहते हैं, x और y निर्देशांक, ऊंचाई और चौड़ाई की एक संख्या है कि (यह MObject फोन की सुविधा देता है)। गुणों को केवीसी दिशानिर्देशों के अनुसार नामित किया गया है (MObject.x; MObject.height, आदि)। मेरा अगला कार्य, एक XML फ़ाइल में पढ़ना है जो इस MObject का वर्णन करता है। दुर्भाग्यवश, एक्सएमएल तत्वों का नाम अलग-अलग रखा गया है - एक्स और वाई, ऊंचाई और चौड़ाई (पूंजीकरण नोट करें)।

आदर्श रूप में, XML तत्वों MObject के गुणों के साथ मेल होगा। इस मामले में, मैं KVC का उपयोग करें और कोड की एक पूरी अजीब से बच सकते हैं:

इस आ केस-संवेदी चाबियों का उपयोग करने के लिए किया जाएगा की
for (xmlProperty in xmlElement) 
{ 
    [MObject setValue:xmlProperty.value forKey:xmlProperty.name]. 
} 

एक तरह से। मैं इसके साथ कहां से शुरू करूंगा? क्या कोई अन्य, बेहतर समाधान है?

सुझावों की बहुत सराहना की गई।

उत्तर

3

-[NSObject valueForKey:] और -[NSObject setValue:forKey:] ओवरराइड करता है, तो आप उसे मदद कर सकते हैं मत करो।

आपका सबसे अच्छा शर्त चाबियाँ आप मक्खी पर एक्सएमएल फ़ाइल से मिलता है परिवर्तित करने के लिए किया जाएगा। रूपांतरण करने के लिए एक अलग विधि का उपयोग करें और आप संपत्ति कुंजी के नामों का कैश भी बनाए रख सकते हैं, इसलिए आपको केवल एक बार प्रत्येक रूपांतरण करने की आवश्यकता है।

- (NSString *)keyForName:(NSString *)name { 
    // _nameToKeyCache is an NSMutableDictionary that caches the key 
    // generated for a given name so it's only generated once per name 
    NSString *key = [_nameToKeyCache objectForKey:name]; 
    if (key == nil) { 
     // ...generate key... 
     [_nameToKeyCache setObject:key forKey:name]; 
    } 
    return key; 
} 

- (void)foo:xmlElement { 
    for (xmlProperty in xmlElement) { 
     [myObject setValue:xmlProperty.value forKey:[self keyForName:xmlProperty.name]]. 
    } 
} 
3

आप NSString के lowercaseString उपयोग करते हैं, छोटे अक्षरों पर एक्सएमएल कुंजी नाम परिवर्तित करने के लिए है कि अगर मदद करता है।

+0

शानदार ढंग से सरल समाधान। बहुत बढ़िया! –

+0

यह काम करेगा, मुझे लगता है कि एकमात्र मुद्दा नामकरण सम्मेलन है। – EightyEight

1

अवहेलना -valueForKey: और -setValue:forKey:

आप शायद ही कुंजी (तत्व/विशेषता नाम) को स्वीकार करना चाहिए आप को पहचान, और अन्य चाबी के लिए super अप करने के लिए कहते हैं।

3

अवहेलना -valueForUndefinedKey: और -setValue:forUndefinedKey:

आप एक अलग पूंजीकरण इसका इस्तेमाल के साथ एक चाबी मिल जाए, अन्यथा super अप करने के लिए कहते हैं।

1

इसलिए मैंने क्रिस हैंनसन के सुझाव को लागू किया और यहां मैं समाप्त हुआ। मैंने इसे अपने यूटिल क्लास में रखा है। यह प्रत्येक वर्ग के लिए एक शब्दकोश रखता है जिसे हम देखते हैं। यह शायद थोड़ा रिफैक्टरिंग का उपयोग कर सकता है लेकिन यह अब तक मेरे लिए बहुत अच्छा काम करता है।

static NSMutableDictionary *keyCache; 

+ (NSString *)keyForClass:(Class)klass column:(NSString *)column { 
    if (!keyCache) { keyCache = [NSMutableDictionary dictionary]; } 

    NSString *className = NSStringFromClass(klass); 

    NSMutableDictionary *tableKeyCache = [keyCache objectForKey:className]; 

    if (!tableKeyCache) { 
     tableKeyCache = [NSMutableDictionary dictionary]; 

     unsigned int numMethods = 0; 
     Method *methods = class_copyMethodList(klass, &numMethods); 
     NSMutableArray * selectors = [NSMutableArray array]; 
     for (int i = 0; i < numMethods; ++i) { 
      SEL selector = method_getName(methods[i]); 
      [selectors addObject:NSStringFromSelector(selector)]; 
     } 
     [tableKeyCache setValue:selectors forKey:@"allSelectors"]; 
     free(methods); 
     [keyCache setValue:tableKeyCache forKey:className]; 
    } 

    NSString *keyToReturn = [tableKeyCache valueForKey:column]; 
    if (!keyToReturn) { 
     for (NSString *columnKey in [tableKeyCache valueForKey:@"allSelectors"]) { 
      if ([column caseInsensitiveCompare:columnKey] == NSOrderedSame) { 
       [tableKeyCache setValue:columnKey forKey:column]; 
       keyToReturn = columnKey; 
       break; 
      } 
     } 
    } 

    if (!keyToReturn) { // Taking a guess here... 
     NSLog(@"Selector not found for %@: %@ ", className, column); 
     keyToReturn = [Utils keyForClass:[klass superclass] column:column]; 
    } 

    return keyToReturn; 
} 
+0

इसके अलावा, #import को न भूलें –