使用KVO与NSNotificationCenter观察对可变阵列的更改

在我的模型中,我有一个名为events的对象数组。 无论何时将新对象添加到事件中,我都希望通知我的控制器。

我认为这样做的一个好方法是使用KVO模式在事件发生变化时得到通知(来自添加的新对象)

// AppDelegate
// events is a NSMutableArray @property/@synthesize etc...

[appDelagate addObserver:self
               forKeyPath:@"events"
                  options:NSKeyValueObservingOptionNew
                  context:NULL];

但observeValueForKeyPath方法没有被调用,我发现数组不符合KVO :-(

一种选择是通过调用keyPath的willChangeValueForKey来手动触发该方法

// ViewController
[self willChangeValueForKey:@"events"];
[self.events addObject:event];
[self didChangeValueForKey:@"events"];

但是这种感觉很重,因为我应该跟踪事件数组的前后状态,以便可以通过observeValueForKeyPath方法访问它。

一种方法是使用标准数组(而不是可变的),并在每次我想添加一个新对象时创建/设置一个新的事件实例,或者我可以创建一个单独的属性来跟踪可变数组(我希望你可以观察@“events.count”)。

另一种选择是使用NSNotificationCenter。 我也读过一些建议使用块的答案(但我不知道从哪里开始)。

最后,我是否可以在我的委托中保存我的控制器实例,并发送相关消息?

// Delegate
[myController eventsDidChange];

从代表保持对控制器的引用很奇怪吗?

我很难理解如何选择哪种方法是最好的,所以任何有关性能,未来代码灵活性和最佳实践的建议都将不胜感激!


您不应该为可变集合制作直接的公共属性,以避免它们在您不知情的情况下发生变异。 NSArray本身不是关键值可观察的,但是你的一对多属性@"events"是。 以下是如何观察它:

首先,为一个不可变的集合声明一个公共属性:

@interface Model
@property (nonatomic, copy) NSArray *events;
@end

然后在你的实现中用一个可变的ivar将它返回:

@interface Model ()
{
    NSMutableArray *_events;
}
@end

并重写getter和setter:

@implementation Model

@synthesize events = _events;

- (NSArray *)events
{
    return [_events copy];
}

- (void)setEvents:(NSArray *)events
{
    if ([_events isEqualToArray:events] == NO)
    {
        _events = [events mutableCopy];
    }
}

@end

如果其他对象需要向模型添加事件,则可以通过调用-[Model mutableArrayValueForKey:@"events"]来获取可变代理对象。

NSMutableArray *events = [modelInstance mutableArrayValueForKey:@"events"];
[events addObject:newEvent];

这将通过每次设置新的收藏集来触发KVO通知。 为了获得更好的性能和更精细的控制,请实现其余的数组访问器。

另请参阅:观察用于插入/删除的NSMutableArray。


根据accessor方法的文档,你应该实现:

- (void)addEventsObject:(Event*)e
{
    [_events addObject:e];
}

- (void)removeEventsObject:(Event*)e
{
    [_events removeObject:e];
}

然后KVO会在调用这些通知时触发通知。

链接地址: http://www.djcxy.com/p/47341.html

上一篇: Observing Changes to a mutable array using KVO vs. NSNotificationCenter

下一篇: How to debug KVO