如何告诉(托管)对象通知其KVO需要回收其中一个属性?

时间:2009-07-25 19:15:25

标签: objective-c cocoa core-data key-value-observing

当我们有一个具有基于其他属性生成的属性的对象时,通常我们实现+keyPathsForValuesAffecting{PropertyName}类方法。

我想要做的事情与我的NSManagedObject上的属性基本相同,但遍历关系。

我的模型很简单;我有两个实体,应用程序和版本(我正在创建一个appcast生成应用程序)。当App的属性发生变化时,因为我实现了上面的方法,所以更改了-appcast字符串,并且所有绑定都得到了适当的更新。

但是,当任何特定应用程序的版本(多对多关系)上的任何属性发生更改时,将无法正确生成-appcast属性。我可以修复/解决方法吗?

1 个答案:

答案 0 :(得分:3)

这是一个迟到的答案,但我认为这是一种常见的情况,答案肯定不是很明显。

我通常会注意要更改的managedObjectContext,然后检查是否有任何已更改的对象是我想要注意的对象。所以,在你的NSManagedObject子类中:

// We need to register for the notification in both awakeFromFetch
// AND awakeFromInsert, since either one could be called, depending on
// if the object was previously-created or not
- (void)awakeFromFetch {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidChange:) name: NSManagedObjectContextObjectsDidChangeNotification object:[self managedObjectContext]];
}

- (void)awakeFromInsert {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidChange:) name: NSManagedObjectContextObjectsDidChangeNotification object:[self managedObjectContext]];
}

- (void)managedObjectContextDidChange:(NSNotification *)notification {
    // Get a set containing ALL objects which have been changed
    NSSet *insertedObjects = [[notification userInfo] objectForKey:NSInsertedObjectsKey];
    NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
    NSSet *deletedObjects = [[notification userInfo] objectForKey:NSDeletedObjectsKey];

    NSSet *changedObjects = [insertedObjects setByAddingObjectsFromSet:updatedObjects];
    changedObjects = [changedObjects setByAddingObjectsFromSet:deletedObjects];

    if ([changedObjects intersectsSet:[self versions]]) {
        [self willChangeValueForKey:@"appCast"];
        [self didChangeValueForKey:@"appCast"];
    }
}

从性能角度来看,这肯定不理想,因为每当对象图中的任何内容发生变化时,此通知都会触发,但我发现这是实现此目的的最直接方式。