Confused about KVO and arrays

Discussion in 'Mac Programming' started by Hookflash, Apr 3, 2010.

  1. Hookflash macrumors newbie

    Joined:
    Sep 15, 2006
    #1
    This whole KVO/KVC thing is throwing me for a loop, particularly when it comes to arrays. My understanding, based on chapter 9 of Hillegass's book, is that, if I want observers of an array to be notified of changes to the array (e.g., insertion and removal of elements), these changes need to happen via a proxy object obtained with "mutableArrayValueForKey." For example, when I add an element like this...

    Code:
    id proxy= [objWithArray mutableArrayValueForKey:@"array"];
    [proxy insertObject:someObject atIndex:0];
    ...then anything observing "array" will be notified. That works as expected. However, Hillegass also says (as far as I can tell) that "proxy" tries to invoke "insertObject:inArrayAtIndex:" on "objWithArray" behind the scenes. This doesn't seem to be happening in my tests. Here's my code:

    Code:
    #import <Foundation/Foundation.h>
    
    @interface Test : NSObject
    {
    	NSMutableArray *things;
    }
    @end
    
    @implementation Test
    
    - (id)init
    {
    	self = [super init];
    	things = [[NSMutableArray alloc] init];
    	return self;
    }
    
    - (void)dealloc
    {
    	[things release];
    	[super dealloc];
    }
    
    
    // This should be called when I mutate 'things' via proxy, right?
    - (void)insertObject:(id)obj inThingsAtIndex:(NSUInteger)i
    {
    	NSLog(@"insertObject:inThingsAtIndex");
    	[things insertObject:obj atIndex:i];
    }
    
    @end
    
    
    
    int main (int argc, const char * argv[]) {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        Test *test = [[Test alloc] init];
    	
        // Get proxy to "things" in "test"
        id proxy = [test mutableArrayValueForKey:@"things"];
    
        // Why doesn't this result in a call to [test insertObject:inThingsAtIndex]?
        [proxy insertObject:@"Hello World!" atIndex:0];
    	
        [test release];
        [pool drain];
        return 0;
    }
    test is an instance of Test which has a mutable array called things. Note that Test implements insertObject:inThingsAtIndex:. However, when I call insertObject:atIndex: on proxy (which was obtained through [test mutableArrayValueForKey:mad:"things"]), this does not result in a call to test insertObject:inThingsAtIndex:. Am I missing something?
     
  2. JoshDC macrumors regular

    Joined:
    Apr 8, 2009
  3. Hookflash thread starter macrumors newbie

    Joined:
    Sep 15, 2006
    #3
    Ok, it seems that removeObjectInThingsAtIndex: has to be implemented as well in order for the proxy to call insertObject:inThingsAtIndex:. Confusion temporarily allayed :)
     

Share This Page