2009-06-30 6 views

risposta

387

objectForKey: è un metodo NSDictionary. Un NSDictionary è una classe di raccolta simile a NSArray, tranne che invece di utilizzare gli indici, utilizza le chiavi per differenziare gli elementi. Una chiave è una stringa arbitraria che fornisci. Nessun due oggetto può avere la stessa chiave (proprio come nessun altro oggetto in un NSArray può avere lo stesso indice).

valueForKey: è un metodo KVC. Funziona con QUALSIASI classe. valueForKey: consente di accedere a una proprietà utilizzando una stringa per il suo nome. Così, per esempio, se ho una classe Account con una proprietà accountNumber, posso effettuare le seguenti operazioni:

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

[newAccount setAccountNumber:anAccountNUmber]; 

NSNumber *anotherAccountNumber = [newAccount accountNumber]; 

Utilizzando KVC, posso accedere alla proprietà in modo dinamico:

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

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

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

Questi sono gruppi equivalenti di dichiarazioni.

So che stai pensando: wow, ma sarcasticamente. KVC non sembra così utile. In effetti, sembra "verboso". Ma quando vuoi cambiare le cose in fase di esecuzione, puoi fare molte cose interessanti che sono molto più difficili in altre lingue (ma questo va oltre lo scopo della tua domanda).

Se si desidera saperne di più su KVC, ci sono molti tutorial se si utilizza Google in particolare a Scott Stevenson's blog. Puoi anche dare un'occhiata allo NSKeyValueCoding Protocol Reference.

Spero che questo aiuti.

+12

valueForKey si comporta in modo diverso per gli oggetti NSDictionary a seconda che la chiave inizi con un simbolo @. – dreamlax

+57

objectForKey: accetta qualsiasi oggetto come chiave, non solo stringhe. L'unico requisito è che la chiave supporti il ​​protocollo NSCopying. –

+0

Entrambi questi punti sono sicuramente veri. NSDictionaries è un caso speciale e non è necessario utilizzare le stringhe per le chiavi. In realtà, non ho preso in considerazione le sottigliezze di entrambi, poiché sembra che il richiedente abbia semplicemente richiesto un confronto semplicistico. –

61

Quando si esegue valueForKey: è necessario assegnargli una NSString, mentre objectForKey: può prendere qualsiasi sottoclasse NSObject come chiave. Questo perché per la codifica dei valori-chiave, le chiavi sono sempre stringhe.

Infatti, la documentazione afferma che, anche quando si dà valueForKey: un NSString, si invocherà objectForKey: comunque a meno che la stringa inizia con una @, nel qual caso si invoca [super valueForKey:], che possono chiamare valueForUndefinedKey: che può sollevare un'eccezione.

+0

puoi per favore darmi il link della documentazione che intendi.grazie. –

+5

@ عليامين: [È proprio qui] (https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/Reference/Reference.html#//apple_ref/doc/uid/ 20000140-BBCIBCDJ) – dreamlax

20

Ecco un buon motivo per utilizzare objectForKey: ove possibile, invece di valueForKey: - valueForKey: con una chiave sconosciuta getterà NSUnknownKeyException dicendo "questa classe non è un valore chiave di codifica-compliant per la chiave".

+5

buono a sapersi che "valueForKey: con una chiave sconosciuta verrà lanciata NSUnknownKeyException che dice" questa classe non è un valore chiave che codifica-compatibile per la chiave " – onmyway133

10

Come detto, il tipo di dati objectForKey: è :(id)aKey mentre il tipo di dati valueForKey: è :(NSString *)key.

Ad esempio:

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. 

Quindi, valueForKey: richiederà solo un valore di stringa ed è un metodo KVC, considerando objectForKey: prenderemo alcun tipo di oggetto.

Il valore in objectForKey sarà accessibile dallo stesso tipo di oggetto.