2012-02-13 12 views
7

क्या एनएस डिक्शनरी में कुंजियों के मूल्यों तक पहुंचने के लिए डॉट नोटेशन के माध्यम से कोई तरीका है?डॉट नोटेशन के माध्यम से NSDictionary एक्सेस करें?

NSDictionary *returnVal = [NSDictionary dictionaryWithObjectsAndKeys:@"Saturn", @"name", @"Gas Giant", @"type", nil]; 
NSLog(@"VALUE: %@", [returnVal valueForKey:@"name"]); // This is how I am doing it now. 
+0

मुझे कुछ मिनट दें, मैं कुछ ऐसा कर दूंगा जो आपको श्रेणी का उपयोग करके डॉट नोटेशन का उपयोग करने देगा। –

+4

@ रिचर्ड जे। रॉसीआईआई मुझे नहीं लगता कि आपको एक श्रेणी के साथ जवाब देना चाहिए। यह कुछ ओबीजे-सी क्षमताओं को दिखाता है, लेकिन इसके लिए यह बहुत बुरा अभ्यास होगा। शायद एक मॉडल ऑब्जेक्ट का सुझाव देना जो 'NSObject' का उप-वर्ग है, एक बेहतर दृष्टिकोण होगा। –

+1

मुझे संदेह है कि आप ओवरराइटिंग के साथ कुछ कर सकते हैं '- (आईडी) मानफॉरंडिफाइडकी:' चूंकि कंपाइलर डॉट को अस्वीकार कर देगा ... – JustSid

उत्तर

1

नहीं, आप इसे सही तरीके से कर रहे हैं। आईओएस दुनिया में, अक्सर सही तरीका एकमात्र तरीका है। :)

यदि आप वास्तव में डॉट नोटेशन (और टाइप की गई वस्तुओं के साथ अन्य अच्छी चीजें प्राप्त करना चाहते हैं) चाहते हैं, तो आपको किसी ऑब्जेक्ट में शब्दकोश प्रस्तुतिकरण को भरना होगा। आमतौर पर मेरा इंटरफ़ेस इस तरह दिखेगा:

@interface FooBar : NSObject { 
    NSString *someData; 
    int someNumber; 
} 

@property (nonatomic, copy) NSString *someData; 
@property (nonatomic, assign) int someNumber; 

+ (FooBar *)FooBarFromDictionary:(NSDictionary *)dataDict; 

@end 

कार्यान्वयन स्पष्ट होना चाहिए। फिर आप

FooBar *fb = [FooBar FooBarFromDictionary:data]; 
NSLog(@"fb.someData = %@", fb.someData); 
+0

तकनीकी रूप से नहीं।आप ब्लॉक और श्रेणियों के साथ कुछ सुंदर पागल सामान कर सकते हैं, मेरे जवाब पर एक झलक ले लो। –

1

नहीं, मुझे ऐसा नहीं लगता है।

संदर्भ मैनुअल से।

Accessing Keys and Values 
– allKeys 
– allKeysForObject: 
– allValues 
– getObjects:andKeys: 
– objectForKey: 
– objectsForKeys:notFoundMarker: 
– valueForKey: 

यह कुंजी और मानों तक पहुंचने का एकमात्र तरीका है। तो आप इसे ठीक कर रहे हैं।

यदि चाबियाँ सार्वजनिक संपत्ति थीं तो आप इसे एक्सेस कर पाएंगे और यह पठनीय था।

6

NSDictionary के लिए कोई डॉट वाक्य रचना नहीं है, लेकिन आदर्श तरीका (कुंजियों का उपयोग) objectForKey: के बजाय valueForKey:

Difference between objectForKey and valueForKey?

+0

धन्यवाद, मैं ऐसा करूँगा, मैं सोच रहा था कि अंतर क्या था। लिंक के लिए धन्यवाद। – fuzzygoat

+0

+1 यह उत्तर मेरे उत्तर से अधिक संक्षिप्त है, इसलिए मैं इसके पक्ष में मेरा हटाना चाहता हूं। –

+0

@fuzzygoat कोई समस्या नहीं, उम्मीद है कि यह मदद की। – kevboh

1

तरीका है कि आप शब्दकोश के तत्व तक पहुँचने के लिए उल्लेख किया है उपयोग कर रहा है विचार करना चाहिए। आप कुछ और करना चाहते हैं, हो सकता है आप

NSArray *allValues = [returnVal allValues]; 

use- कर सकते हैं अब इस पंक्ति का उपयोग करते साथ ही आप कार्य कर सकते हैं। और यदि आप कुछ विशिष्ट चाहते हैं तो इसका जिक्र करें, इसके लिए हो सकता है कि कुछ और तरीका हो।

साथ ही NSDictionary क्लास में कोई भी संपत्ति परिभाषित नहीं होगी, इसलिए डॉट नोटेशन सीधे संभव नहीं है।

0

तकनीकी तौर पर, आप कुछ इस तरह कर सकते हैं:

typedef id (^valueBlock)(id); 
@interface NSDictionary(dotNotationAddons) 

@property(nonatomic, readonly) valueBlock value; 

@end 

@implementation NSDictionary(dotNotationAddons) 

-(valueBlock) value 
{ 
    return [[^(id key) { 
     return [self objectForKey:key]; 
    } copy] autorelease]; 
} 

@end 

int main (int argc, const char * argv[]) 
{ 
    @autoreleasepool { 
     NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"1", @"One", @"2", @"Two", @"3", @"Three", @"4", @"Four", nil]; 

     id value = dictionary.value(@"One"); 

     NSLog(@"%@", value); 
    } 


    return 0; 
} 

अगर वह यह है कि आप क्या देख रहे थे मैं नहीं जानता, लेकिन मुझे आशा है कि यह मदद करता है!

+0

मुझे समझ में नहीं आता कि कोई ईमानदारी से वोट क्यों देगा। यह जवाब देता है कि ओपी ने क्या पूछा, मैं डॉट नोटेशन के साथ एक शब्दकोश का उपयोग कैसे कर सकता हूं। यह इसके लिए अनुमति देता है। –

+2

यह दिलचस्प है लेकिन यह @ fuzzygoat के प्रश्न से कैसे संबंधित है? – benzado

+0

@ बेंजाडो क्योंकि यह उसे एनएस डिक्शनरी को डॉट-नोटेशन के साथ उपयोग करने देता है, जो वह चाहता था? –

5

वास्तव में नहीं, नहीं।

डॉट नोटेशन उस चयनकर्ता नाम के साथ एक विधि को कॉल करने का एक शॉर्टेंड तरीका है। दूसरे शब्दों में, यह ...

NSLog(@"Hello, %@", foo.bar.name); 

... इस रूप में ही है ...

NSLog(@"Hello, %@", [[foo bar] name]); 

जब मैं कहता हूँ "एक ही", मेरा मतलब है कि वे एक ही कोड के लिए नीचे संकलित किए जाते हैं । यह सिर्फ वाक्य रचनात्मक चीनी है।

एक सादा NSDictionary इस तरह से कार्य नहीं करेगा।

NSLog(@"Hello, %@", [foo valueForKeyPath:@"bar.name"]); 

तुम सच में अपने कोड में foo.bar.name लिखने के लिए हालांकि, सक्षम होने के लिए चाहते हैं तो आपके होगा: आप कुंजी मान कोडिंग, जो आप valueForKeyPath फोन इस तरह गुण प्राप्त करने की सुविधा देता है के साथ नकली इसके बारे में सॉर्ट कर सकता है एक कस्टम क्लास बनाएं जो forwardInvocation: ओवरराइड करता है; यह आपको किसी ऑब्जेक्ट को अज्ञात संदेश पकड़ने देता है और इसके साथ कुछ और करने के अलावा कुछ भी करता है। इस मामले में, आप अज्ञात चयनकर्ता को उस NSDictionary इंस्टेंस पर लुकअप में बदल सकते हैं।

लेकिन यदि आपने ऐसा किया है, तो संकलक शायद तब भी चेतावनी उत्पन्न करेगा जब तक कि आपने हेडर फाइलें नहीं बनाईं जो उन संपत्ति नामों को अस्तित्व में घोषित करती हैं।

3

मैं NSDictionary से अधिकतर उत्तरों से सहमत हूं objectForKey: या इसी तरह के तरीकों से पहुंचा जाना चाहिए। हालांकि NSDictionary पर डॉट नोटेशन पहुंच की अनुमति देना संभव है, और सीखने के उद्देश्यों के लिए यह किसी के लिए दिलचस्प हो सकता है। इसके अलावा जब उदाहरण के लिए आप AFNetworking के माध्यम से बड़े JSON शब्दकोश पुनर्प्राप्त कर रहे हैं, तो यह विधि आपके कोड की पहुंच और पठनीयता को कम कर सकती है।

DictionaryProperties.h:

यह मेरा समाधान है (कक्षा संपत्ति पहुँच के लिए NSDictionary लपेटकर)

@interface DictionaryProperties : NSObject{ 
    NSMutableDictionary* _backingDict; 
} 

@property (nonatomic, strong) NSMutableDictionary* backingDict; 

+ (DictionaryProperties*) allocWithDictionary:(NSDictionary*)dict; 

@end 

DictionaryProperties.m:

#import "DictionaryProperties.h" 

@implementation DictionaryProperties 

@synthesize backingDict = _backingDict; 

- (id) initWithDictionary:(NSDictionary*)dict { 
    if (self) { 
     if ([dict isKindOfClass:[NSMutableDictionary class]]) { 
      self.backingDict = (id)dict; 
     } else { 
      self.backingDict = [[NSMutableDictionary alloc] initWithDictionary:dict]; 
     } 
    } 
    return self; 
} 
+ (DictionaryProperties*) allocWithDictionary:(NSDictionary*)dict { 
    return [[DictionaryProperties alloc] initWithDictionary:dict]; 
} 


- (void)forwardInvocation:(NSInvocation *)invocation 
{ 
    NSString* key = NSStringFromSelector(invocation.selector); 
    invocation.selector = @selector(objectForKey:); 
    [invocation setArgument:&key atIndex:2]; 

    if ([self.backingDict objectForKey:key]) { 
     [invocation invokeWithTarget:self.backingDict]; 
    } else { 
     [self doesNotRecognizeSelector:invocation.selector]; 
    } 
} 

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{ 
    return [self.backingDict methodSignatureForSelector:@selector(objectForKey:)]; 

} 
@end 

ExampleDictContent.h: (कक्षा शब्दकोश के अंदर क्या है घोषित करना)

#import "DictionaryProperties.h" 

@interface ExampleDictContent : DictionaryProperties 

@property (strong, nonatomic) NSString* someData; 
@property (strong, nonatomic) NSString* someOtherData; 

@end 

@implementation ExampleDictContent 
@end 

उपयोग: (एक शब्दकोश की साधारण घोषणा, आवरण और संपत्ति का उपयोग के आवंटन)

#import "ExampleDictContent.h" 

NSDictionary* d = [NSDictionary dictionaryWithObjects:NSArray arrayWithObjects:@"someData content", @"someOtherData content", nil 
               forKeys:NSArray arrayWithObjects:@"someData", @"someOtherData", nil]; 

ExampleDictContent* dictWProps = [ExampleDictContent allocWithDictionary:d]; 

NSLog(dictWProps.someData); 
NSLog(dictWProps.someData); 

यह प्रिंट होगा: NSDictionary पहुँचने के लिए एक मुखौटा के रूप में

someData content 
someOtherData content 

तो मूल रूप से DictionaryProperties काम करता है। शब्दकोष पर कॉल करें get-property विधि कॉल को getObjectForKey: में कनवर्ट करने के लिए forwardInvocation का उपयोग करता है। मुझे इसके बारे में क्या पसंद है, यह है कि यह शब्दकोश पर स्वत: पूर्णता की अनुमति देता है, और मुझे यह स्पष्ट रूप से घोषित करने की अनुमति देता है कि मैं किस कुंजी को एक्सेस करना चाहता हूं (ExampleDictContent.h फ़ाइल में)। ध्यान दें कि यह समाधान गुणों के लिए लेखन पहुंच की अनुमति नहीं देता है, लेकिन इसे नीचे दिए गए लिंक में दिखाए गए अनुसार जोड़ा जा सकता है।

यह समाधान आंशिक रूप से karstenlitsche's solution से प्रेरित किया गया है। मुख्य अंतर यह है कि यह समाधान श्रेणियों के बजाय उप-वर्गीकरण पर आधारित है।

+0

[डाउनलोड करने योग्य \ [एच | एम \] फाइलें] (https://gist.github.com/warpling/829e93a1357e9ef7f282) :) – Warpling

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