This article describes the basic principles of key-value coding.
Keys and Key Paths
Getting Values Using Key-Value Coding
Setting Values Using Key-Value Coding
A key is a string that identifies a specific property of an object. Typically, a key corresponds to the name of an accessor method or instance variable in the receiving object. Keys must use ASCII encoding, begin with a lowercase letter, and may not contain whitespace.
Some example keys would be payee, openingBalance, transactions and amount.
A key path is a string of dot separated keys that is used to specify a sequence of object properties to traverse. The property of the first key in the sequence is relative to the receiver, and each subsequent key is evaluated relative to the value of the previous property.
For example, the key path address.street would get the value of the address property from the receiving object, and then determine the street property relative to the address object.
The method valueForKey: returns the value for the specified key, relative to the receiver. If there is no accessor or instance variable for the specified key, then the receiver sends itself a valueForUndefinedKey: message. The default implementation of valueForUndefinedKey: raises an NSUndefinedKeyException; however subclasses can override this behavior.
Similarly, valueForKeyPath: returns the value for the specified key path, relative to the receiver. Any object in the key path sequence that is not key-value coding compliant for the appropriate key receives a valueForUndefinedKey: message.
The method dictionaryWithValuesForKeys: retrieves the values for an array of keys relative to the receiver. The returned NSDictionary contains values for all the keys in the array.
Note: Collection objects, such as NSArray and NSDictionary, can’t contain nil as a value. Instead, nil values are represented by a special object, NSNull. NSNull provides a single instance that represents the nil value for object properties. The default implementations of dictionaryWithValuesForKeys: and setValuesForKeysWithDictionary: translates between NSNull and nil automatically, so your objects don’t have to explicitly test for NSNull values.
When a value is returned for a key path that contains a key for a to-many property, and that key is not the last key in the path, the returned value is an array containing all the values for the keys to the right of the array key. For example, requesting the value of the key path transactions.payee returns an array containing all the payee objects, for all the transactions. This also works for multiple arrays in the key path. The key path accounts.transactions.payee would return an array with all the payee objects, for all the transactions, in all the accounts.
The method setValue:forKey: sets the value of the specified key, relative to the receiver, to the provided value. The default implementation of setValue:forKey: determines the data type that the accessor or instance variable expects and sets the appropriate value. The conversion process is discussed in detail in “Scalar and Structure Support.”
If the specified key does not exist, the receiver is sent a setValue:forUndefinedKey: message. The default implementation of setValue:forUndefinedKey: raises an NSUndefinedKeyException; however, subclasses can override this method to handle the request in a custom manner.
The method setValue:forKeyPath: behaves in a similar fashion, but it is able to handle a key path as well as a single key.
Finally, setValuesForKeysWithDictionary: sets the properties of the receiver with the values in the specified dictionary, using the dictionary keys to identify the properties. The default implementation invokes setValue:forKey: for each key-value pair, substituting nil for NSNull objects as required.
One additional issue that you should consider is what happens when an attempt is made to set a non-object property to a nil value. In this case, the receiver sends itself a setNilValueForKey: message. The default implementation of setNilValueForKey: raises an NSInvalidArgumentException. Your application can override this method to substitute a default value or a marker value, and then invoke setValue:forKey: with the new value.
Last updated: 2007-06-06