使用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