如何告诉(托管)对象通知其 KVO 需要重新缓存其属性之一?

Posted

技术标签:

【中文标题】如何告诉(托管)对象通知其 KVO 需要重新缓存其属性之一?【英文标题】:How do I tell a (managed) object to notify its KVOs that one of its properties needs to be recached? 【发布时间】:2009-07-25 19:15:25 【问题描述】:

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

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

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

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

【问题讨论】:

要明确:appCastApp 上的一个属性,当您更改Version 上的值时(可能是通过App 链接到versions 属性或类似)appCast 属性不发送更改通知? 【参考方案1】:

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

我通常会观察 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"];
    

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

【讨论】:

以上是关于如何告诉(托管)对象通知其 KVO 需要重新缓存其属性之一?的主要内容,如果未能解决你的问题,请参考以下文章

KVO:如何告诉观察者,那个自我改变了?

NSFetchedResultsController 在托管对象被修改时通知其委托删除更改,并且从不通知插入或更新

如何调试对象发送 KVO 通知的原因?

刨根问底KVO原理

在 Cocoa 中,我是不是需要在释放对象时从接收 KVO 通知中删除它?

[深入浅出Cocoa]详解键值观察(KVO)及其实现机理