On Aug 5, 2008, at 11:50 PM, Jeff Johnson wrote:

On Aug 5, 2008, at 10:22 AM, Roland King wrote:

I've now read the KVC documentation quite a number of times .. especially with regards to indexed accessor properties trying to really understand them. After a bit of messing about in code this is my understanding ..

1) if your property is an array you don't need to supply the countOf<key> and objectIn<key>AtIndex: methods for reading the Array, it will use the Array directly. You can supply them if you want in which case it will use them.

2) If you don't supply the mutable access methods insertObject:in<key>AtIndex: and removeObjectFrom<key>AtIndex: but your property is a NSArray, it will still actually work, what will happen is the entire array property will be set each time you mutate it using KVC or bindings to a brand new array, not very efficient.

3) 2) above is true not only for an NSArray, (obviously as it's not mutable) but for an NSMutableArray too. Even if your property is a NSMutableArray which could be mutated, if you haven't supplied the mutable access methods, it won't be, the entire array will be replaced each time. (this surprised me). If you want the efficient insert/remove for your NSMutableArray property, you have to write the accessor methods explicitly.


1) didn't suprise me as the documentation indicates you only need the accessor methods when the property isn't an array. 2) surprised me a bit as the documentation states that to have mutable access you *must* implement two extra methods. However if your entire property is an NSArray or subclass thereof, you don't have to implement them, it just does it rather slowly. 3) did surprise me a bit given that 2) worked, I expected if it was smart enough to work around the absence of the mutator methods in the case of an NSArray, it would realize the property was a MutableArray, and mutate it directly, but no, it does it the slow way.

I could imagine not bothering to write the mutator methods just seeing that it worked automagically and never realising that the entire Array is being swapped out each time I changed it, probably not very efficient. So the moral of the story for me is .. if I want any multi-value for a key, even if the underlying instance variable is an array, write the accessor/mutator methods every time.

Roland,

How are you mutating your array? If you do [[myObject mutableArrayValueForKey:@"myArray"] addObject:anObject], it should preserve the current NSMutableArray even without indexed accessors. This seems to work in my testing, at least.

-Jeff


I don't get that in my testing. As trivial an example as I can make below, Foo, one property, prop, it's a NSMutableArray*, has a getter and a setter. The main() function calls

[ [ foo mutableArrayValueForKey:@"prop" ] addObject:@"something" ]

and that replaces the array by calling setProp:, doesn't mutate the one there.

Only when I add both (not just the insert, but both insert and remove) of the mutator methods, will access via the mutableArrayForKey call insertObject:inPropAtIndex:



@interface Foo : NSObject {
        NSMutableArray *prop;
}

-(id)init;
-(void)dealloc;

-(NSMutableArray*)prop;
-(void)setProp:(NSMutableArray*)propVal;

@end



@implementation Foo

-(id)init
{
        self = [ super init ];
        if( self )
        {
                prop = [ [ NSMutableArray alloc ] init ];
        }
        
        return self;
}
-(void)dealloc
{
        [ prop dealloc ];
        [ super dealloc ];
}

-(NSMutableArray*)prop
{
        return prop;
}
-(void)setProp:(NSMutableArray*)propVal
{
        [ propVal retain ];
        [ prop release ];
        prop = propVal;
}

@end



int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        
    Foo *foo = [ [ Foo alloc ] init ];
        
[[ foo mutableArrayValueForKey:@"prop" ] addObject:@"Another String" ];
        
    [pool drain];
    return 0;
}

_______________________________________________

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 [EMAIL PROTECTED]

Reply via email to