开发者

key-value coding and to-many relationships

I'm a bit confused with key value coding and to-many relationships. I've read that when having such relationship I should use [object mutableArrayValueForKey:@"key"]; to retrieve the mutable array that holds the objects in that ordered relationship.

What I don't understand is what's the difference between mutableArrayValueForKey or just valueForKey.

Let me illustrate with an example (a开发者_StackOverflowrray is an NSMutableArray of self setup as a property):

id array1= [self valueForKey:@"array"];

NSLog(@"first element %@",[array1 objectAtIndex:1]);

id array2 = [self mutableArrayValueForKey:@"array"];

NSLog(@"first element %@",[array2 objectAtIndex:1]);

Both calls return exactly the same. In that case, what is the benefit or different of the second one?

Cheers!


mutableArrayValueForKey does not return "array", it returns a proxy for "array." You can see this if you print out the classes:

NSLog(@"%@", [self.array class]);
NSLog(@"%@", [[self valueForKey:@"array"] class]);
NSLog(@"%@", [[self mutableArrayValueForKey:@"array"] class]);

This prints:

2010-02-24 20:06:44.258 Untitled[25523:a0f] NSCFArray
2010-02-24 20:06:44.275 Untitled[25523:a0f] NSCFArray
2010-02-24 20:06:44.276 Untitled[25523:a0f] NSKeyValueSlowMutableArray

Read over the documentation for mutableArrayValueForKey for details on how that proxy works. In this particular case, you happen to have a real NSMutableArray as an ivar. But what if there were no such ivar? You can implement KVC without an ivar backing the property, with methods like countOf<Key> and objectIn<Key>AtIndex:. There's no rule that there be an actual "array" ivar, as long as you can return sensible results to the KVC methods.

But what if you want to expose an NSMutableArray interface, but you don't have a real NSMutableArray? That's what mutableArrayValueForKey is for. It returns a proxy that when accessed will translate into KVC methods back to you, including sending you mutating to-many methods like insertObject:in<Key>AtIndex:.

This even happens in the case that you have a real ivar (as in your case), you just don't notice it because the proxy behaves so much like the real object.


The first element is actually objectAtIndex:0, not objectAtIndex:1.

Also, the second method ensures that you can modify the returned array with addObject: and removeObjectAtIndex:, even if the value for the key @"array" is an immutable array.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜