অবজেক্টফো এবং মান ফোরকির মধ্যে পার্থক্য?


345

মধ্যে পার্থক্য কি objectForKeyএবং valueForKey? আমি ডকুমেন্টেশনে উভয়কেই দেখলাম এবং সেগুলি আমার কাছে একই রকম মনে হয়েছিল।

উত্তর:


403

objectForKey:একটি NSDictionaryপদ্ধতি। একটি NSDictionaryহ'ল অনুরূপ একটি সংগ্রহ শ্রেণি NSArray, সূচিগুলি ব্যবহার না করে আইটেমগুলির মধ্যে পার্থক্য করার জন্য এটি কী ব্যবহার করে। কীটি আপনার সরবরাহ করা একটি স্বেচ্ছাসেবী স্ট্রিং। কোনও দুটি বস্তুর একই কী থাকতে পারে না (যেমন কোনও দুটি বস্তুর NSArrayএকই সূচক থাকতে পারে না)।

valueForKey:একটি কেভিসি পদ্ধতি। এটি যে কোনও ক্লাসের সাথে কাজ করে। valueForKey:আপনাকে তার নামের জন্য স্ট্রিং ব্যবহার করে কোনও সম্পত্তি অ্যাক্সেস করার অনুমতি দেয়। সুতরাং উদাহরণস্বরূপ, আমার Accountকোনও সম্পত্তি সহ একটি ক্লাস থাকলে আমি accountNumberনিম্নলিখিতটি করতে পারি:

NSNumber *anAccountNumber = [NSNumber numberWithInt:12345];
Account *newAccount = [[Account alloc] init];

[newAccount setAccountNumber:anAccountNUmber];

NSNumber *anotherAccountNumber = [newAccount accountNumber];

কেভিসি ব্যবহার করে, আমি গতিসম্পন্নভাবে সম্পত্তিটি অ্যাক্সেস করতে পারি:

NSNumber *anAccountNumber = [NSNumber numberWithInt:12345];
Account *newAccount = [[Account alloc] init];

[newAccount setValue:anAccountNumber forKey:@"accountNumber"];

NSNumber *anotherAccountNumber = [newAccount valueForKey:@"accountNumber"];

সেগুলি বিবৃতিগুলির সমতুল্য সেট।

আমি জানি আপনি চিন্তা করছেন: বাহ, কিন্তু ব্যঙ্গাত্মকভাবে। কেভিসি সমস্ত দরকারী মনে হয় না। আসলে, এটি "শব্দযুক্ত" দেখায়। তবে আপনি যখন রানটাইমের সময় জিনিসগুলি পরিবর্তন করতে চান, আপনি প্রচুর শীতল জিনিসগুলি করতে পারেন যা অন্যান্য ভাষাগুলিতে আরও বেশি কঠিন (তবে এটি আপনার প্রশ্নের ক্ষেত্রের বাইরে)।

আপনি যদি কেভিসির বিষয়ে আরও জানতে চান তবে বিশেষত স্কট স্টিভেনসনের ব্লগে গুগল করা থাকলে অনেক টিউটোরিয়াল রয়েছে । আপনি NSKeyValueCoding প্রোটোকল রেফারেন্সও পরীক্ষা করে দেখতে পারেন ।

আশা করি এইটি কাজ করবে.


12
মানটিফোর্কি এনএসডেটরিজ অবজেক্টের জন্য আলাদা আলাদা আচরণ করে তার উপর নির্ভর করে কীটি @ প্রতীক দিয়ে শুরু হয়।
ড্রিমলাক্স

61
অবজেক্টফোকি: যে কোনও বস্তুকে কেবল স্ট্রিং নয়, একটি কী হিসাবে গ্রহণ করে। একমাত্র প্রয়োজনীয়তা কীটি এনএসকোপিং প্রোটোকলটিকে সমর্থন করে।
অ্যাশলে ক্লার্ক

5
আমি অবাক হয়েছি কেউ এই উত্তরটি ফরওয়ার্কি দ্বারা চিহ্নিত করে সংশোধন করেনি: প্রযুক্তিগতভাবে আপনাকে সংশ্লিষ্ট ইনস্ট্যান্স ভেরিয়েবলের অ্যাক্সেস দেয় না, বরং অ্যাক্সেসর পদ্ধতি যা (উদাহরণস্বরূপ) উদাহরণটি পরিবর্তনশীল পরিচালনা করতে পারে।
ড্যানি জুমা

7
সতর্কতা: মান ফরফোকে তীব্রভাবে ধীর হতে পারে - এটি বর্তমানে আমার আইপ্যাড অ্যাপ্লিকেশনটিতে একটি বড় প্রতিবন্ধক, এত ধীর যে এটিকে "স্ট্যান্ডার্ড" অভিধানে প্রতিস্থাপনের ফলে অ্যাপটি লক্ষণীয়ভাবে দ্রুততর হয়ে উঠেছে। আইওএসে কেভিসির সাথে খুব খারাপ কিছু, এবং আমি এটি আর কখনও ব্যবহার করব না - পারফরম্যান্সের হ্রাসের পক্ষে নয় এবং যাইহোক এটি দীর্ঘপথে পুনরায় লিখতে হবে। এটি ক্যালায়ার্সে এনএসএসস্ট্রিং মানগুলির সাথে এনএসএসস্ট্রিং কী ব্যবহার করছিল। উপকরণগুলি দেখিয়েছে যে "CAObject_valueForKey" ছিল মোট রানটাইমের 25% (!)
অ্যাডাম

2
@ অ্যাডাম এটি ভীতিজনক শোনায়। আপনি কি iOS7 এর পরে আবার চেষ্টা করেছেন? যদি তা হয়, তবে কি পরে জিনিসগুলি পরিবর্তিত হয়েছে?
আনহেলিগ

64

যখন তুমি কর valueForKey: এটি দরকার এটি একটি objectForKey:এনএসএসস্ট্রিং দেওয়ার দরকার হয়, যেখানে কোনও এনএসবজেক্ট সাবক্লাসটি কী হিসাবে নিতে পারে। এটি কারণ কী-মান কোডিংয়ের জন্য, কীগুলি সর্বদা স্ট্রিং থাকে।

প্রকৃতপক্ষে, ডকুমেন্টেশনে বলা হয়েছে যে আপনি যখন valueForKey:এনএসএসটিং প্রদান করেন তখনও এটি objectForKey:স্ট্রিংটি শুরু না করা সত্ত্বেও তা ডাকবে @, যার ক্ষেত্রে এটি আহ্বান জানায় [super valueForKey:], যা valueForUndefinedKey:ব্যতিক্রম বাড়াতে পারে call


আপনি দয়া করে আমাকে যে ডকুমেন্টেশনের লিঙ্কটি বলতে চান তা দিতে পারেন? ধন্যবাদ.
আলী আমিন

5
@ আলীমিন: এটি ঠিক এখানে
০৯

20

objectForKey:পরিবর্তে যেখানেই সম্ভব সেখানে ব্যবহারের এক দুর্দান্ত কারণ valueForKey:- valueForKey:একটি অজানা কীটি NSUnknownKeyException"এই শ্রেণীর কীটির জন্য কী মান কোডিং-সম্মতিযুক্ত নয়" বলে নিক্ষেপ করবে ।


5
"ভ্যালুফোরকি" জেনে ভাল, একটি অজানা কী দিয়ে এনএসইউনফেনডকি কি এক্সেক্সশনটি নিক্ষেপ করবে "এই ক্লাসটি কীটির মূল কোডিং-
আনুষাঙ্গিক নয়

এটি এনএসডিকোরিয়ানের সাথে কেবল সত্য নয়, এবং এটি চেষ্টা করার জন্য আপনাকে স্বাগতম: এনএসএলগ (@ "জেড:% @", [@ {@ "এক্স": @ (10), @ "ওয়াই": @ (20)} valueForKey: @ "জেড"]); মান ফোর্সকি অন্য শ্রেণীর উপর এই জাতীয় ব্যতিক্রমগুলি নির্গমন করবে যা একটি নির্দিষ্ট কী সমর্থন করে না - তবে এনএসডি অভিধান সাবক্লাসের জন্য - আপনি কেবল একটি শান্ত শূন্য পাবেন। এটি ব্যবহার করে দেখুন:
মটি শ্নের

13

যেমনটি বলা হয়েছে, 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একই ধরণের বস্তু দ্বারা অ্যাক্সেস করা হবে।


0

আমি এখানে একটি বিস্তৃত উত্তর দেওয়ার চেষ্টা করব। বেশিরভাগ পয়েন্ট অন্যান্য উত্তরে উপস্থিত হয় তবে আমি প্রতিটি উত্তর অসম্পূর্ণ এবং কিছুটি ভুল পেয়েছি।

প্রথম এবং সর্বাগ্রে, objectForKey:একটি NSDictionaryপদ্ধতি, যখনvalueForKey: কোনও কেভিসি অভিযোগ শ্রেণীর জন্য প্রয়োজনীয় কেভিসি প্রোটোকল পদ্ধতি - এনএসডিকোরিয়াসহ।

তদ্ব্যতীত, @dreamlax যেমন লিখেছিলেন, ডকুমেন্টেশন নির্দেশ যে NSDictionaryতার প্রয়োগ valueForKey:পদ্ধতি ব্যবহার তার objectForKey:বাস্তবায়ন। অন্য কথায় - [NSDictionary valueForKey:]কল[NSDictionary objectForKey:]

এর থেকে বোঝা যায় যে এর valueForKey:চেয়ে দ্রুত আর কখনও হতে পারে নাobjectForKey: (একই ইনপুট কীতে) এর যদিও পুরো পরীক্ষায় আমি প্রায় 5% থেকে 15% পার্থক্য করেছি, বিলিয়ন বিলিয়ন এলোমেলো অ্যাক্সেসকে বিশাল এনএসডিকোরিয়ামে পেয়েছি। সাধারণ পরিস্থিতিতে - পার্থক্য নগণ্য।

পরবর্তী: কেভিসি প্রোটোকল কেবল NSString *কীগুলির সাথে কাজ করে , সুতরাং valueForKey:কেবল NSString *(বা সাবক্লাস) কী হিসাবে গ্রহণ করবে , NSDictionaryঅন্য ধরণের বস্তুর সাথে কী হিসাবে কাজ করতে পারে - যাতে "নিম্ন স্তরের" objectForKey:কোনও অনুলিপি-সক্ষম (এনএসকোপিং প্রোটোকল অনুবর্তী) অবজেক্ট গ্রহণ করে চাবি হিসাবে

সর্বশেষ, NSDictionary'sবাস্তবায়ন valueForKey:মান আচরণ KVC এর ডকুমেন্টেশন সংজ্ঞায়িত থেকে বিচ্যুত, এবং একটি নির্গত করা হবে না 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);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.