回答:
objectForKey:
あるNSDictionary
方法。AnはNSDictionary
に似たコレクションクラスでNSArray
、代わりにインデックスを使用する場合を除き、それはアイテムを区別するためにキーを使用しています。キーは、ユーザーが指定する任意の文字列です。2つのオブジェクトが同じキーを持つことはできません(同じオブジェクトに2つのオブジェクトがNSArray
同じインデックスを持つことはできません)。
valueForKey:
KVCメソッドです。ANYクラスで動作します。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はそれほど便利に見えません。実際、それは「言葉っぽい」ように見えます。しかし、実行時に物事を変更したい場合、他の言語でははるかに難しい多くのクールなことができます(ただし、これは質問の範囲を超えています)。
KVCについてさらに詳しく知りたい場合は、特にスコットスティーブンソンのブログでGoogleのチュートリアルをご覧ください。NSKeyValueCodingプロトコルリファレンスもご覧ください。
お役に立てば幸いです。
その場合はvalueForKey:
、NSStringを指定する必要がありますが、objectForKey:
任意のNSObjectサブクラスをキーとして使用できます。これは、Key-Valueコーディングの場合、キーが常に文字列であるためです。
実際には、あなたが与えるも、ドキュメントの状態valueForKey:
NSStringのは、それが起動します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:
文字列値のみを受け取り、KVCメソッドですが、objectForKey:
任意のタイプのオブジェクトを受け取ります。
の値にobjectForKey
は、同じ種類のオブジェクトがアクセスします。
ここで包括的な答えを提供するように努めます。ポイントの多くは他の回答にも出ていますが、私はそれぞれの回答が不完全で、一部が間違っていることに気付きました。
何よりobjectForKey:
もまず、NSDictionary
メソッドですが、valueForKey:
NSDictionaryのを含む-任意KVCのクレームクラスに要求KVCプロトコル方式です。
さらに、@dreamlaxように、その、ドキュメントのヒントを書いたNSDictionary
その実装valueForKey:
方法を使用したそのobjectForKey:
実装を。言い換えれば[NSDictionary valueForKey:]
、[NSDictionary objectForKey:]
。
これは、それが、意味valueForKey:
よりも速くなることはありませんobjectForKey:
(同じ入力キーで)ます。通常の状況では、違いはごくわずかです。
次へ:KVCプロトコルはNSString *
キーでのみ機能するため、キー(またはサブクラス)valueForKey:
のみをNSString *
キーとして受け入れ、NSDictionary
他の種類のオブジェクトはキーとして機能します-「下位レベル」objectForKey:
はコピー可能な(NSCopyingプロトコルに準拠した)オブジェクトを受け入れますキーとして。
最後に、のNSDictionary's
実装はvalueForKey:
、KVCのドキュメントで定義されている標準の動作から逸脱し、NSUnknownKeyException
「特殊な」キー(「@」で始まるキーでない限り、通常は「集約」ファンクションキー(例@"@sum, @"@avg"
)。代わりに、NSDictionaryでキーが見つからない場合は単にnilを返します。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);
}