On Jan 19, 2009, at 3:27 PM, Quincey Morris wrote:

2. If some change affects which objects are cached, update the cache array KVO-compliantly. (Use standard NSMutableArray methods on [yourCacheOwner mutableArrayValueForKey: @"yourCacheArray"] instead of yourCacheArray.)

This is common advice, but in my opinion it's misguided.

While directly mutating an array ivar doesn't generate KVO notifications, and mutating the proxy returned by - mutableArrayValueForKey: does, that's not the best means to gain KVO compliance. You should instead implement the indexed to-many accessors[1] for any to-many property. Then, you should use them to mutate the property in your own code.

What's wrong with -mutableArrayValueForKey:?

Here's one good guideline: in general, KVC is for accessing a property based on dynamic data rather than compile-time identifier. If you find yourself hard-coding string literals with property names, then You're Doing It Wrong(tm).

More importantly, -mutableArrayValueForKey: doesn't magically allow for mutations to the property that aren't already allowed by your class's interface. In particular, if you don't provide the indexed to- many accessors, then mutating the proxy returned by - mutableArrayValueForKey: ends up doing the inefficient call to set<Key>: that you were trying to avoid. (In other words, it has the same negative implications as will/didChangeValueForKey:.) Since that's the case, why not just call -set<Key>: yourself rather than having the proxy do it?

(There is an exception to the above, but it's hardly worth mentioning. If your property has neither indexed to-many mutator methods nor the simple setter method, and +accessInstanceVariablesDirectly returns YES, then the proxy may directly access the NSMutableArray-like ivar. In that case, the proxy can do efficient operations on the property along with efficient KVO notifications using did/willChange:valuesAtIndexes:forKey:. However, except for cases of backward compatibility, you should always override +accessInstanceVariablesDirectly to return NO for your classes. Allowing KVC to directly modify your internal state without going through your methods is bad mojo.)

Regards,
Ken

[1] The indexed to-many accessors for array properties are described here:

http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/AccessorConventions.html#/ /apple_ref/doc/uid/20002174-178830-BAJEDEFB

See also the documentation for -mutableArrayValueForKey: although some additional methods are only documented in NSKeyValueCoding.h at the declaration of -mutableArrayValueForKey:.

The (non-indexed) to-many accessors for set properties are described in the documentation for -mutableSetValueForKey:.

_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to