观察 NSArrayController 变化:检测插入或删除
Posted
技术标签:
【中文标题】观察 NSArrayController 变化:检测插入或删除【英文标题】:Observing NSArrayController changes: detect insertion or deletion 【发布时间】:2014-05-23 07:19:04 【问题描述】:我有一个 NSArrayController 绑定到我的核心数据模型中的实体“地址”。我想监视哪些新对象插入到此地址实体中,或者哪些现有对象被删除。我正在尝试通过 KVO 做到这一点,但我不确定我应该如何去做。
在我的 awakeFromNib 中,我将视图控制器类添加为“arrangedObjects”的观察者:
[self.addressArrayController addObserver:self
forKeyPath:@"arrangedObjects"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:@"Address"];
我确实收到了观察者通知:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
if( object == self.addressArrayController)
// what do do here?
问题是更改字典总是为零(我相信是由于苹果长期存在的错误),所以我不知道添加或删除了哪个对象,甚至不知道添加或删除了什么!而且我确实需要添加或删除的确切对象,理想情况下不必遍历该实体的所有对象并尝试根据对象的时间戳或任何其他标准找出答案。
最好的方法是什么?
【问题讨论】:
在这种情况下,您的意思是new
和old
列表是NSNull
,对吗?我不是这是否是一个错误,但它肯定是一种长期存在的行为(至少 10.4)并且记录不足。但是,即使字典不是空的,它们也无用,因为我从未在arrangedObjects
上看到不是NSKeyValueChangeSetting
的通知,new
和old
只是数组的副本,因此无论如何您都必须进行完整的差异遍历。由于您使用的是 Core Data,您是否尝试过NSManagedObjectContextObjectsDidChangeNotification
?
谢谢。在这种情况下使用上下文通知很有意义。
【参考方案1】:
改编自 my answer here,其中列出了 gaige 在 cmets 中建议的代码。
注册 NSManagedObjectContextObjectsDidChangeNotification:
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(mocDidChangeNotification:)
name:NSManagedObjectContextObjectsDidChangeNotification
object: nil];
并在相应的方法中解析userInfo字典:
- (void)mocDidChangeNotification:(NSNotification *)notification
NSManagedObjectContext* savedContext = [notification object];
// Ignore change notifications for anything but the mainQueue MOC
if (savedContext != self.managedObjectContext)
return;
// Ignore updates -- lots of noise from maintaining user-irrelevant data
// Log insertion
for (NSManagedObject* insertedObject in
[notification.userInfo valueForKeyPath:NSInsertedObjectsKey])
if ([insertedObject isKindOfClass:[Address class]] )
NSLog(@"Inserted Address");
// Log deletion
for (NSManagedObject* deletedObject in
[notification.userInfo valueForKeyPath:NSDeletedObjectsKey])
if ([deletedObject isKindOfClass:[Address class]] )
NSLog(@"Deleted Address");
【讨论】:
如果模型没有存储在 CoreData 中,这将如何工作?以上是关于观察 NSArrayController 变化:检测插入或删除的主要内容,如果未能解决你的问题,请参考以下文章
如何将 NSArrayController 的内容集绑定到多个 NSArrayController 选择?