观察NSArrayController更改:检测插入或删除

时间:2014-05-23 07:19:05

标签: macos cocoa core-data cocoa-bindings nsarraycontroller

我有一个NSArrayController,它绑定到我的Core Data模型中的实体“Address”。我想监视哪些新对象插入到此Address实体中,或者删除哪些现有对象。我试图通过KVO这样做,但我不确定我应该怎么做。

在我的awakeFromNib中,我添加了视图控制器类作为“arrangeObjects”的观察者:

[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?
   }
}

问题是更改词典总是为零(由于一些长期存在的Apple bug,我相信),所以我不知道添加或删除了哪个对象,甚至添加或删除了某些内容!而且我确实需要添加或删除的确切对象,理想情况下,无需遍历此实体的所有对象,并尝试根据对象的时间戳或任何其他标准进行计算。

这样做的最佳方式是什么?

1 个答案:

答案 0 :(得分:4)

改编自my answer here,其中列出了gaige在评论中建议的代码。

注册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");
        }
    }

}