जवाबों:
objectForKey:
एक NSDictionary
विधि है। एक NSDictionary
एक के समान एक संग्रह वर्ग है NSArray
, बजाय अनुक्रमणिका का उपयोग कर के अलावा, यह कुंजी का उपयोग करता है आइटम के बीच अंतर करने के लिए। एक कुंजी एक मनमाना स्ट्रिंग है जो आप प्रदान करते हैं। किसी भी दो वस्तुओं में एक ही कुंजी नहीं हो सकती है (जिस तरह एक में दो वस्तुओं में एक NSArray
ही सूचकांक नहीं हो सकता है)।
valueForKey:
KVC विधि है। यह किसी भी वर्ग के साथ काम करता है। valueForKey:
आपको इसके नाम के लिए एक स्ट्रिंग का उपयोग करके एक संपत्ति का उपयोग करने की अनुमति देता है। उदाहरण के लिए, यदि मेरे पास Account
संपत्ति के साथ एक वर्ग है , तो मैं accountNumber
निम्नलिखित कर सकता हूं:
NSNumber *anAccountNumber = [NSNumber numberWithInt:12345];
Account *newAccount = [[Account alloc] init];
[newAccount setAccountNumber:anAccountNUmber];
NSNumber *anotherAccountNumber = [newAccount accountNumber];
KVC का उपयोग करके, मैं संपत्ति को गतिशील रूप से एक्सेस कर सकता हूं:
NSNumber *anAccountNumber = [NSNumber numberWithInt:12345];
Account *newAccount = [[Account alloc] init];
[newAccount setValue:anAccountNumber forKey:@"accountNumber"];
NSNumber *anotherAccountNumber = [newAccount valueForKey:@"accountNumber"];
वे बयानों के समतुल्य सेट हैं।
मुझे पता है कि आप सोच रहे हैं: वाह, लेकिन व्यंग्यात्मक रूप से। KVC यह सब उपयोगी नहीं दिखता है। वास्तव में, यह "वर्डी" दिखता है। लेकिन जब आप रनटाइम में चीजों को बदलना चाहते हैं, तो आप बहुत सारी शांत चीजें कर सकते हैं जो अन्य भाषाओं में बहुत अधिक कठिन हैं (लेकिन यह आपके प्रश्न के दायरे से बाहर है)।
यदि आप केवीसी के बारे में अधिक जानना चाहते हैं, तो कई ट्यूटोरियल हैं यदि आप विशेष रूप से स्कॉट स्टीवेन्सन के ब्लॉग पर Google । आप NSKeyValueCoding प्रोटोकॉल संदर्भ भी देख सकते हैं ।
उम्मीद है की वो मदद करदे।
जब आपको valueForKey:
इसकी आवश्यकता होती है तो आप इसे NSString दे objectForKey:
सकते हैं , जबकि किसी भी NSObject उपवर्ग को एक कुंजी के रूप में ले सकते हैं। ऐसा इसलिए है क्योंकि की-वैल्यू कोडिंग के लिए, चाबियाँ हमेशा तार होती हैं।
वास्तव में, प्रलेखन में कहा गया है कि जब आप valueForKey:
एक एनएसएसट्रिंग देते हैं, objectForKey:
तब भी यह वैसे ही आह्वान करेगा जब तक कि स्ट्रिंग एक के साथ शुरू नहीं होती है @
, जिस स्थिति में यह आह्वान करता है [super valueForKey:]
, जो valueForUndefinedKey:
कि एक अपवाद को बढ़ा सकता है।
यहां एक objectForKey:
संभव कारण का उपयोग करने के बजाय एक महान कारण है valueForKey:
- valueForKey:
एक अज्ञात कुंजी के साथ NSUnknownKeyException
यह कहते हुए फेंक देगा कि "यह वर्ग कुंजी के लिए महत्वपूर्ण मूल्य कोडिंग-अनुरूप नहीं है"।
जैसा कि कहा गया है, objectForKey:
डेटाटाइप है :(id)aKey
जबकि valueForKey:
डेटाटाइप है :(NSString *)key
।
उदाहरण के लिए:
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSArray arrayWithObject:@"123"],[NSNumber numberWithInteger:5], nil];
NSLog(@"objectForKey : --- %@",[dict objectForKey:[NSNumber numberWithInteger:5]]);
//This will work fine and prints ( 123 )
NSLog(@"valueForKey : --- %@",[dict valueForKey:[NSNumber numberWithInteger:5]]);
//it gives warning "Incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString *'" ---- This will crash on runtime.
तो, valueForKey:
केवल एक स्ट्रिंग मान लेगा और एक केवीसी विधि है, जबकि objectForKey:
किसी भी प्रकार की वस्तु ले जाएगा।
मूल्य objectForKey
को उसी तरह के ऑब्जेक्ट द्वारा एक्सेस किया जाएगा।
मैं यहाँ एक व्यापक उत्तर देने की कोशिश करूँगा। अधिकांश बिंदु अन्य उत्तरों में दिखाई देते हैं, लेकिन मैंने प्रत्येक उत्तर को अधूरा पाया, और कुछ गलत।
सबसे पहले और सबसे महत्वपूर्ण, objectForKey:
एक NSDictionary
विधि है, जबकिvalueForKey:
केवीसी शिकायत वर्ग के लिए आवश्यक एक केवीसी प्रोटोकॉल विधि है - जिसमें एनएसडीआई भी शामिल है।
इसके अलावा, @dreamlax के रूप में लिखा था, प्रलेखन संकेत है कि NSDictionary
इसके लागू करता है valueForKey:
विधि का उपयोग कर अपने objectForKey:
कार्यान्वयन। दूसरे शब्दों में - [NSDictionary valueForKey:]
पर कॉल करता है[NSDictionary objectForKey:]
।
इसका तात्पर्य यह है कि इससे valueForKey:
तेज कभी नहीं हो सकताobjectForKey:
(एक ही इनपुट कुंजी पर) हालांकि पूरी तरह से परीक्षण मैंने लगभग 5% से 15% अंतर के साथ किया है, अरबों से अधिक विशाल पहुंच के लिए यादृच्छिक पहुंच पर। सामान्य स्थितियों में - अंतर नगण्य है।
अगला: केवीसी प्रोटोकॉल केवल NSString *
कुंजी के साथ काम करता है , इसलिए valueForKey:
केवल NSString *
कुंजी के रूप में (या उपवर्ग) को स्वीकार करेगा , जबकि कुंजी के रूप में NSDictionary
अन्य प्रकार की वस्तुओं के साथ काम कर सकता है - ताकि "निचला स्तर" objectForKey:
किसी भी कॉपी-सक्षम (NSCopying प्रोटोकॉल अनुरूप) को स्वीकार कर ले। कुंजी के रूप में।
अंतिम, केवीसी के प्रलेखन में परिभाषित मानक व्यवहार से विचलन का NSDictionary's
कार्यान्वयन valueForKey:
, और NSUnknownKeyException
यह एक कुंजी के लिए उत्सर्जन नहीं करेगा जो इसे नहीं मिल सकता है - जब तक कि यह "विशेष" कुंजी नहीं है - जो कि '@' से शुरू होता है - जिसका आमतौर पर मतलब है " एकत्रीकरण "फ़ंक्शन कुंजी (जैसे @"@sum, @"@avg"
)। इसके बजाय, यह एनएसएल में एक कुंजी नहीं मिलने पर बस एक शून्य लौटाएगा - जैसा व्यवहार करनाobjectForKey:
मेरे नोट्स को प्रदर्शित करने और साबित करने के लिए कुछ परीक्षण कोड निम्नलिखित हैं।
- (void) dictionaryAccess {
NSLog(@"Value for Z:%@", [@{@"X":@(10), @"Y":@(20)} valueForKey:@"Z"]); // prints "Value for Z:(null)"
uint32_t testItemsCount = 1000000;
// create huge dictionary of numbers
NSMutableDictionary *d = [NSMutableDictionary dictionaryWithCapacity:testItemsCount];
for (long i=0; i<testItemsCount; ++i) {
// make new random key value pair:
NSString *key = [NSString stringWithFormat:@"K_%u",arc4random_uniform(testItemsCount)];
NSNumber *value = @(arc4random_uniform(testItemsCount));
[d setObject:value forKey:key];
}
// create huge set of random keys for testing.
NSMutableArray *keys = [NSMutableArray arrayWithCapacity:testItemsCount];
for (long i=0; i<testItemsCount; ++i) {
NSString *key = [NSString stringWithFormat:@"K_%u",arc4random_uniform(testItemsCount)];
[keys addObject:key];
}
NSDictionary *dict = [d copy];
NSTimeInterval vtotal = 0.0, ototal = 0.0;
NSDate *start;
NSTimeInterval elapsed;
for (int i = 0; i<10; i++) {
start = [NSDate date];
for (NSString *key in keys) {
id value = [dict valueForKey:key];
}
elapsed = [[NSDate date] timeIntervalSinceDate:start];
vtotal+=elapsed;
NSLog (@"reading %lu values off dictionary via valueForKey took: %10.4f seconds", keys.count, elapsed);
start = [NSDate date];
for (NSString *key in keys) {
id obj = [dict objectForKey:key];
}
elapsed = [[NSDate date] timeIntervalSinceDate:start];
ototal+=elapsed;
NSLog (@"reading %lu objects off dictionary via objectForKey took: %10.4f seconds", keys.count, elapsed);
}
NSString *slower = (vtotal > ototal) ? @"valueForKey" : @"objectForKey";
NSString *faster = (vtotal > ototal) ? @"objectForKey" : @"valueForKey";
NSLog (@"%@ takes %3.1f percent longer then %@", slower, 100.0 * ABS(vtotal-ototal) / MAX(ototal,vtotal), faster);
}