Dov'è la differenza tra setObject: forKey: e setValue: forKey: in NSMutableDictionary?


153

Quando guardo la documentazione, quasi non vedo grandi differenze. Sia "valore" che "oggetto" sono di tipo id , quindi può essere qualsiasi oggetto. Key è una volta una stringa e nell'altro caso un id. Uno di questi sembra trattenere l'oggetto, l'altro no. Cos'altro? Quale è per quale caso?


Risposte:


163

setValue:forKey:fa parte del protocollo NSKeyValueCoding , che tra l'altro consente di accedere alle proprietà degli oggetti come Interface Builder. setValue:forKey:è implementato in classi diverse da NSDictionary.

setObject:forKey:è NSMutableDictionary'smotivo di esistere. La sua firma sembra essere abbastanza simile a setValue: forKey :, ma è più generica (ad es. Qualsiasi tipo di chiave). È in qualche modo una coincidenza che le firme siano così simili.

Ciò che aggiunge confusione è che l'implementazione di NSMutableDictionary setValue:forKey:è equivalente setObject:forKey:nella maggior parte dei casi. In altre classi, setValue:forKey:cambia le variabili membro. In NSMutableDictionary, cambia le voci del dizionario, a meno che non si anteponga alla chiave un carattere "@", nel qual caso modifica le variabili del membro.

Quindi, in poche parole, usare setObject:forKey:quando è necessario lavorare con chiavi e valori del dizionario e setValue:forKey:nei casi più rari in cui è necessario affrontare KVP .

EDIT: e oh, sembra che questo sia già stato chiesto e risposto prima: differenza tra objectForKey e valueForKey?


quella domanda non è esattamente la stessa. riguarda i metodi getter, mentre questa domanda riguarda i metodi setter
user102008

1
Che cosa intendi con "In NSMutableDictionary, cambia le voci del dizionario, a meno che non si anteponga la chiave con un carattere '@', nel qual caso modifica le variabili membro." Quali variabili membro? Inoltre potresti commentare stackoverflow.com/questions/5755917 ? Grazie.
Peter Štibraný,

solo per completezza, setObject: forKey genererà (eccezione) se l'oggetto è zero. SetValue: forKey si comporterà allo stesso modo o rimuoverà l'oggetto esistente dal dizionario quando si imposta zero per chiave?
Motti Shneor,

Bella risposta. Veramente. per completezza, però, sarebbe bello ricordare che (almeno su NSMutableDictionary) setValue: forKey: tollera i valori zero e rimuove la voce - mentre setObject: forKey: genererà eccezioni e arresti anomali quando vengono consegnati valori nulli.
Motti Shneor,

83

Un'altra differenza è che se si assegna un valore nullo setValue:forKey:, rimuove la chiave dal dizionario se esiste, altrimenti non fa nulla. Ma se dai un valore nullo a setObject:forKey:, si genera un'eccezione.


10
Questo è molto utile da sapere. Altrimenti avevo scritto la mia categoria su NSMutableDictionary per ottenere esattamente questo !. Grazie
Arman,

2
Un'altra differenza è con la sottoscrizione obiett-c, è possibile scrivere dic[key] = value;per supportare la rimozione della chiave se il valore è nil. La sottoscrizione è generalmente un approccio migliore rispetto setValue:forKey:a raggiungere questo obiettivo.
Cœur


4

anObject - Il valore per chiave. L'oggetto riceve un messaggio di conservazione prima di essere aggiunto a NSDictionary. Questo valore non deve essere nullo.

aKey - La chiave per il valore. La chiave viene copiata (usando copyWithZone:; le chiavi devono essere conformi al NSCopyingprotocollo). La chiave non deve essere nulla.

valore - Il valore per chiave.

chiave - La chiave per il valore. Si noti che quando si utilizza la codifica dei valori-chiave, la chiave deve essere una stringa (consultare "Nozioni fondamentali sulla codifica dei valori-chiave").


Grazie per aver fornito il motivo per cui setObject: forKey: solleva un'eccezione. @breakfreehg
simbesi.com
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.