Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Key-Value-Observing a to-many relationship in Cocoa

I am trying to get key-value-observing to work for an NSMutableArray. Below is the .h file for MyObservee, the observed class:

@interface MyObservee : NSObject {
    @private int someValue;
    @private NSMutableArray *someArray;
}

@property (readwrite,assign) int someValue;
- (NSMutableArray *)someArray;
@end

The class MyObserver implements observeValueForKeyPath:ofObject:change:context:. Here is how I add the observer:

MyObservee *moe = [[MyObservee alloc] init];
MyObserver *mobs = [[MyObserver alloc] init];

[moe addObserver:mobs 
      forKeyPath:@"someArray" 
         options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) 
         context:NULL];

[moe.someArray addObject:@"hi there"];

How come the addObject: message isn't triggering as a change to the someArray key path? I have a feeling there's something I don't fully understand here.

like image 682
Sam Lee Avatar asked Jan 25 '09 05:01

Sam Lee


1 Answers

You need to implement the indexed array accessors as defined in the KVC programming guide. Then you must use those accessors to access the array and the KVO triggering will work. You can also call -mutableArrayValueForKey: and use that array to addObject: and such and it will in turn call the accessor methods and the KVO triggering will occur as well. There are also set accessors for use in for NSSets, see here and here.

Example:

@interface MyClass : NSObject
{
    NSMutableArray *_orders;
}

@property(retain) NSMutableArray *orders;

- (NSUInteger)countOfOrders;
- (id)objectInOrdersAtIndex:(NSUInteger)index;
- (void)insertObject:(id)obj inOrdersAtIndex:(NSUInteger)index;
- (void)removeObjectFromOrdersAtIndex:(NSUInteger)index;
- (void)replaceObjectInOrdersAtIndex:(NSUInteger)index withObject:(id)obj;


@end
like image 112
robottobor Avatar answered Sep 25 '22 13:09

robottobor