Documentation Archive Developer
Search
PATH  Documentation > WebObjects 4.5 > EOControl Reference

Table of Contents

EOKeyValueCoding


(informal protocol)
Declared in:
EOControl/EOKeyValueCoding.h



Protocol Description


The EOKeyValueCoding informal protocol defines Enterprise Objects Framework's main data transport mechanism, in which the properties of an object are accessed indirectly by name (or key), rather than directly through invocation of an accessor method or as instance variables. Thus, all of an object's properties can be accessed in a consistent manner. the Framework additions to NSObject provide default implementations of EOKeyValueCoding, which are sufficient for most purposes.

The basic methods for accessing an object's values are takeValue:forKey:, which sets the value for the property identified by the specified key, and valueForKey:, which returns the value for the property identified by the specified key. The default implementations provided by NSObject use the accessor methods normally implemented by objects (or to access instance variables directly if need be), so that you don't have to write special code simply to integrate your objects into the Enterprise Objects Framework.

The corresponding methods takeStoredValue:forKey: and storedValueForKey: are similar, but they're considered to be a private API, for use by the Framework for transporting data to and from trusted sources. For example, takeStoredValue:forKey: is used to initialize an object's properties with values fetched from the database, whereas takeValue:forKey: is used to modify an object's properties to values provided by a user or other business logic. How these methods work and how they're used by the framework is discussed in more detail in the section "Stored Value Methods" .

Both the basic and stored value key-value coding methods cache attribute bindings for both accessor methods and instance variables, making lookups efficient. The method flushAllKeyBindings is provided to clear these bindings-as you should when you add or modify a class in the run-time system.

The the methods accessInstanceVariablesDirectly and useStoredAccessor are used by enterprise object classes to modify the behavior of the default implementations of key-value coding methods. The remaining methods, handleQueryWithUnboundKey:, handleTakeValue:forUnboundKey:, and unableToSetNullForKey:, are provided to handle error conditions. The default versions of handleQueryWithUnboundKey: and handleTakeValue:forUnboundKey: raise EOUnknownKeyException, with the target object (EOTargetObjectUserInfoKey) and key (EOUnknownUserInfoKey) in the user info.

For more information on EOKeyValueCoding, see the sections:



Constants


In EOKeyValueCoding.h, EOControl defines an enumeration with two constants to be used as possible arguments for the createKeyValueBindingForKey and keyValueBindingForKey methods. The argument indicates whether the return value, a EOKeyBinding object, binds a class/key pair to a mechanism to set the value for a key or to retrieve it.


ConstantDescription
EOSetKeyBindingMaskDesignates a binding as one responsible for setting an object's value.
EOStoredKeyBindingMaskDesignates a binding as one responsible for retrieving an object's value.



Method Types


Accessing values
- storedValueForKey:
- takeStoredValue:forKey:
- takeValue:forKey:
- valueForKey:
Changing default behavior
+ accessInstanceVariablesDirectly
+ useStoredAccessor
Flushing key bindings
+ flushAllKeyBindings
Handling error conditions
- handleQueryWithUnboundKey:
- handleTakeValue:forUnboundKey:
- unableToSetNullForKey:


Class Methods



accessInstanceVariablesDirectly

+ (BOOL)accessInstanceVariablesDirectly

Returns YES if the key-value coding methods should access the corresponding instance variable directly on finding no accessor method for a property. Returns NO if they shouldn't. NSObject's implementation of this method returns YES. Subclasses can override it to return NO, in which case the key-value coding methods won't access instance variables.

flushAllKeyBindings

+ (void)flushAllKeyBindings

Invalidates the cached key binding information for all classes (caches are kept of key-to-method or instance variable bindings in order to make key-value coding efficient). This method should be invoked whenever a class is modified in or removed from the run-time system.

useStoredAccessor

+ (BOOL)useStoredAccessor

Returns YES if the stored value methods ( storedValueForKey: and takeStoredValue:forKey:) should use private accessor methods in preference to public accessors. Returning NO causes the stored value methods to use the same accessor method-instance variable search order as the corresponding basic key-value coding methods ( valueForKey: and takeValue:forKey:). NSObject's implementation of this method returns YES.


Instance Methods



handleQueryWithUnboundKey:

- (id)handleQueryWithUnboundKey:(NSString *)key

Invoked from valueForKey: when it finds no property binding for key. NSObject's implementation raises an EOUnknownKeyException, with the target object (EOTargetObjectUserInfoKey) and key (EOUnknownUserInfoKey) in the user info. Subclasses can override this method to handle the query in some other way.

handleTakeValue:forUnboundKey:

- (void)handleTakeValue:(id)value forUnboundKey:(NSString *)key

Invoked from takeValue:forKey: when it finds no property binding for key. NSObject's implementation raises an EOUnknownKeyException, with the target object (EOTargetObjectUserInfoKey) and key (EOUnknownUserInfoKey) in the user info. Subclasses can override it to handle the request in some other way.

storedValueForKey:

- (id)storedValueForKey:(NSString *)key

Returns the property identified by key. This method is used when the value is retrieved for storage in an object store (generally, this is ultimately in a database) or for inclusion in a snapshot. The default implementation provided by the Framework additions to NSObject is similar to the implementation of valueForKey:, but it resolves key with a different method-instance variable search order:
  1. Searches for a private accessor method based on key (a method preceded by an underbar). For example, with a key of "lastName", storedValueForKey: looks for a method named _getLastName or _lastName.
  2. If a private accessor isn't found, searches for an instance variable based on key and returns its value directly. For example, with a key of "lastName", storedValueForKey: looks for an instance variable named _lastName or lastName.
  3. If neither a private accessor or an instance variable is found, storedValueForKey: searches for a public accessor method based on key. For the key "lastName", this would be getLastName or lastName.
  4. If key is unknown, storedValueForKey: calls handleTakeValue:forUnboundKey:.

This different search order allows an object to bypass processing that is performed before returning a value through public API. However, if you always want to use the search order in valueForKey:, you can implement the class method useStoredAccessor to return NO. And as with valueForKey:, you can prevent direct access of an instance variable with the method the class method accessInstanceVariablesDirectly.



takeStoredValue:forKey:

- (void)takeStoredValue:(id)value forKey:(NSString *)key

Sets the property identified by key to value. This method is used to initialize the receiver with values from an object store (generally, this is ultimately from a database) or to restore a value from a snapshot. The default implementation provided by the Framework additions to NSObject is similar to the implementation of takeValue:forKey:, but it resolves key with a different method-instance variable search order:
  1. Searches for a private accessor method based on key (a method preceded by an underbar). For example, with a key of "lastName", takeStoredValue:forKey: looks for a method named _setLastName:.
  2. If a private accessor isn't found, searches for an instance variable based on key and sets its value directly. For example, with a key of "lastName", takeStoredValue:forKey: looks for an instance variable named _lastName or lastName.
  3. If neither a private accessor or an instance variable is found, takeStoredValue:forKey: searches for a public accessor method based on key. For the key "lastName", this would be setLastName:.
  4. If key is unknown, takeStoredValue:forKey: calls handleTakeValue:forUnboundKey:.

This different search order allows an object to bypass processing that is performed before setting a value through public API. However, if you always want to use the search order in takeValue:forKey:, you can implement the class method useStoredAccessor to return NO. And as with valueForKey:, you can prevent direct access of an instance variable with the method the class method accessInstanceVariablesDirectly.



takeValue:forKey:

- (void)takeValue:(id)value forKey:(NSString *)key

Sets the value for the property identified by key to value, invoking handleTakeValue:forUnboundKey: if the receiver doesn't recognize key and unableToSetNullForKey: if value is nil and key identifies a scalar property.

The default implementation provided by the Framework additions to NSObject works as follows:

  1. Searches for a public accessor method of the form setKey:, invoking it if there is one.
  2. If a public accessor method isn't found, searches for a private accessor method of the form _setKey:, invoking it if there is one.
  3. If an accessor method isn't found and the class method accessInstanceVariablesDirectly returns YES, takeValue:forKey: searches for an instance variable based on key and sets the value directly, autoreleasing the old value and retaining the new one. For the key "lastName", this would be _lastName or lastName.
  4. If neither an accessor method nor an instance variable is found, the default implementation invokes handleTakeValue:forUnboundKey:.


unableToSetNullForKey:

- (void)unableToSetNilForKey:(NSString *)key

Invoked from takeValue:forKey: (and takeStoredValue:forKey:) when it's given a nil value for a scalar property (such as an int or a float). NSObject's implementation raises an NSInvalidArgumentException. Subclasses can override it to handle the request in some other way, such as by substituting zero or a sentinel value and invoking takeValue:forKey: again.

valueForKey:

- (id)valueForKey:(NSString *)key

Returns the value for the property identified by key, invoking handleQueryWithUnboundKey: if the receiver doesn't recognize key.

The default implementation provided by the Framework additions to NSObject works as follows:

  1. Searches for a public accessor method based on key. For example, with a key of "lastName", valueForKey: looks for a method named getLastName or lastName.
  2. If a public accessor method isn't found, searches for a private accessor method based on key (a method preceded by an underbar). For example, with a key of "lastName", valueForKey: looks for a method named _getLastName or _lastName.
  3. If an accessor method isn't found and the class method accessInstanceVariablesDirectly returns YES, valueForKey: searches for an instance variable based on key and returns its value directly. For the key "lastName", this would be _lastName or lastName.
  4. If neither an accessor method nor an instance variable is found, the default implementation invokes handleQueryWithUnboundKey:.



Table of Contents