Observing Changes to a mutable array using KVO vs. NSNotificationCenter

青春壹個敷衍的年華 提交于 2019-11-28 18:48:43
Ryder Mackay

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!