On Jan 19, 2009, at 15:11, Ken Thomases wrote:

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?

Sorry, you are correct. Assuming you're not depending on direct instance variable access, my statement should have been:

Use standard NSMutableArray methods on [yourCacheOwner mutableArrayValueForKey: @"yourCacheArrayProperty"] instead of yourCacheArray, and implement the 2 or 3 required indexed accessor methods to make it work.

In that case, using those indexed accessor methods directly *may* be more convenient than using the mutableArrayValueForKey proxy, but they are only a limited subset of the methods available to NSArray and NSMutableArray. If you want to use addObject: or removeAllObjects or addObjectsFromArray: etc, you're going to have to provide boilerplate implementations of all of them, which translate them into the few basic accessors. It's easy, but tedious to do over and over, for each new property. (I tried that, and decided to go back to using the proxy before long.)

You can easily hide the ugly compile time string by corralling it into a single method: define a @property (readonly) NSMutableArray* mutableYourCacheArrayProperty that returns the proxy object.


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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 arch...@mail-archive.com

Reply via email to