观察到的变化使用KVO与NSNotificationCenter一个可变的阵列(Observing

2019-06-24 04:16发布

在我的模型我有一个名为事件对象的数组。 我想每当一个新的对象被添加到事件通知我的控制器。

我认为,一个好办法做到这一点是使用国际志愿者组织模式(添加从一个新的对象)的事件发生变化时得到通知

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

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

observeValueForKeyPath方法不会被调用,我发现数组是不兼容的志愿:-(

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

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

但是,这感觉沉重,因为我可能还跟踪的之前和之后我的事件阵列的状态,以便它可以从observeValueForKeyPath方法访问。

一种方法可以是使用标准的数组(而不是可变的),并创建/设置事件的新实例我要添加一个新的对象,每次,我也可以做持续跟踪有多少项目是在一个单独的属性可变数组(我希望你能看到@“events.count”)。

另一种选择是使用NSNotificationCenter。 我也看到了一些答案使用块暗示(但我不知道从哪里开始上)。

最后,我可以保持我的控制器的一个实例,在我的委托,只是发送相关消息?

// Delegate
[myController eventsDidChange];

它是奇怪,以保持从委托控制器的参考?

我努力理解如何选择这是最好的方法使用,所以对性能,将来的代码的灵活性和最佳做法的任何意见是非常感谢!

Answer 1:

你不应该为可变集合直接的公共性质,以避免它们在您不知情的变异。 NSArray是不是键值观察的本身,而是你的一个一对多的财产 @"events"是。 以下是如何观察它:

首先,申报不可变集合的公共属性:

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

然后在你实现了可变伊娃支持它:

@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];

这将每段时间设定属性与一个新的集合触发志愿通知。 为了获得更好的性能和更精细的控制,落实其余阵列存取 。

另请参见: 观察一个NSMutableArray的插入/移除 。



Answer 2:

每对访问方法的文档 ,你应该实现:

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

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

然后,志愿将触发通知这些被调用时。



文章来源: Observing Changes to a mutable array using KVO vs. NSNotificationCenter