Observing Changes to a mutable array using KVO vs. NSNotificationCenter
You should not make direct public properties for mutable collections to avoid them mutating without your knowledge. NSArray
is not key-value observable itself, but your one-to-many property @"events"
is. Here's how to observe it:
First, declare a public property for an immutable collection:
@interface Model@property (nonatomic, copy) NSArray *events;@end
Then in your implementation back it with a mutable ivar:
@interface Model (){ NSMutableArray *_events;}@end
and override the getter and setter:
@implementation Model@synthesize events = _events;- (NSArray *)events{ return [_events copy];}- (void)setEvents:(NSArray *)events{ if ([_events isEqualToArray:events] == NO) { _events = [events mutableCopy]; }}@end
If other objects need to add events to your model, they can obtain a mutable proxy object by calling -[Model mutableArrayValueForKey:@"events"]
.
NSMutableArray *events = [modelInstance mutableArrayValueForKey:@"events"];[events addObject:newEvent];
This will trigger KVO notifications by setting the property with a new collection each time. For better performance and more granular control, implement the rest of the array accessors.
See also: Observing an NSMutableArray for insertion/removal.
Per the docs on accessor methods, you should implement:
- (void)addEventsObject:(Event*)e{ [_events addObject:e];}- (void)removeEventsObject:(Event*)e{ [_events removeObject:e];}
Then KVO will fire the notifications when these are called.