In order for key-value coding to locate the accessor methods to use for an invocation of valueForKey: or setValue:forKey:, you need to follow the Cocoa conventions for naming accessor methods.
Commonly Used Accessor Patterns
Indexed Accessor Patterns for To-Many Properties
Typically, the format for an accessor method that returns a property is -<key>. The -<key> method returns an object, scalar or a supported data structure. The alternate naming form -is<Key> is supported as well.
The example in Listing 1 shows the method declaration for the hidden property using the typical convention, and Listing 2 shows the alternate format.
Listing 1 Accessor naming variations for a hidden property key
- (BOOL)hidden { |
// implementation specific code |
return ...; |
} |
Listing 2 Alternate form accessor for a hidden property key
- (BOOL)isHidden { |
// implementation specific code |
return ...; |
} |
In order for an attribute or to-one relationship property to support setValue:forKey: an accessor in the form -set<Key>: must be implemented. Listing 3 shows an accessor method for the hidden property key.
Listing 3 Accessor naming convention to support a hidden property key
- (void)setHidden:(BOOL)flag { |
// implementation specific code |
return; |
} |
Although your application can implement accessor methods for to-many relationship properties using the -<key> and -set<Key>: accessor forms, you may be able to increase performance, in some cases dramatically, by implementing the indexed accessor methods described in “Indexed Accessor Patterns for To-Many Properties.”
You can also support to-many relationships by implementing the indexed accessor methods for those properties. These methods make it possible to support key-value coding for to-many relationships where the related objects aren’t stored in an array. Implementing indexed accessors methods for a property makes that property indistinguishable from an array when using key-value coding methods.
Supporting to-many relationships in this manner requires that your class implement two methods using the naming pattern -countOf<Key> and -objectIn<Key>AtIndex:. The -countOf<Key> method returns the number of objects in the to-many relationship as an unsigned integer. The -objectIn<Key>AtIndex: method returns the object at the specified index in the to-many relationship.
Listing 4 shows the method declarations for a to-many relationship property transactions.
Listing 4 Alternate form accessors for the to-many transactions property
- (unsigned int)countOfTransactions { |
// implementation specific code |
return ...; |
} |
- (Transaction *)objectInTransactionsAtIndex:(unsigned int)index { |
// implementation specific code |
return ...; |
} |
Implementing these methods allows your application to invoke valueForKey: using the key for the to-many property. An array containing the objects in the relationship is returned.
If benchmarking indicates that performance improvements are required, you can also implement -get<Key>:range:. Your implementation of this accessor should return in the buffer given as the first parameter the objects that fall within the range specified by the second parameter. Listing 5 shows an example implementation of this accessor pattern.
Listing 5 Example accessor using the -get<Key>:range: pattern
- (void)getTransaction:(Transaction **)transactions range:(NSRange)inRange { |
// Return the objects in the specified range in the provided |
// buffer. For example, if the transactions were stored in an |
// underlying NSArray |
[transactionsArray getObjects:transactions range:inRange]; |
} |
The key-value coding methods mutableArrayValueForKey: and mutableArrayValueForKeyPath: provide mutable access to a to-many relationship, regardless of the class used to model the relationship.
In order to support these methods, your class must implement two additional methods for each of these keys: -insertObject:in<Key>AtIndex: and -removeObjectFrom<Key>AtIndex:. The -insertObject:in<Key>AtIndex: method is passed the object to insert, and an unsigned int that specifies the index where it should be inserted. The -removeObjectFrom<Key>AtIndex: method is passed an unsigned int value specifying the index of the object to be removed from the relationship. The example in Listing 6 shows the methods required to support mutableArrayValueForKey: for the to-many transactions property.
Listing 6 Supporting mutableArrayValueForKey: for the to-many transactions property
- (void)insertObject:(Transaction *)transaction |
inTransactionsAtIndex:(unsigned int)index { |
// implementation specific code |
return; |
} |
- (void)removeObjectFromTransactionsAtIndex:(unsigned int)index { |
// implementation specific code |
return; |
} |
Optionally, you can also implement -replaceObjectIn<Key>AtIndex:withObject: to improve performance. This method should replace the object at the specified index with the new object.
Last updated: 2007-06-06