替代覆盖didChangeValueForKey:在NSManagedObject上

时间:2012-03-09 13:38:43

标签: ios core-data key-value-observing

我有一个托管对象充当播放列表,它与播放列表项有很多关系。可以有多个播放列表,但只有一个“活动”播​​放列表。活动播放列表由托管对象上的布尔属性指示。

我将活动播放列表中的项目数显示为标签栏项目上的徽章。标签栏项表示的视图控制器正在侦听在更新活动播放列表的内容时触发的特定通知。

我已经实现了这一点,我认为这是一种笨拙的方式,并希望做得更好。它现在可以工作,但我对它不满意。

目前,awakeFromFetch上的每个播放列表对象检查它是否是活动的,如果是,则将自身(使用键值观察)注册为关键路径的观察者,该关键路径是关键路径。关系。当它观察到更改时,它会触发通知,这会导致标签栏项自行更新。

如果播放列表丢失或获得活动状态,则会停止或开始正确观察自身,因此通知仅从活动播放列表中触发。

我想放弃所有自我观察的KVO代码,因为我担心各种进入和退出点以及何时适当地添加和删除观察者。看起来太脏了。

我想覆盖didChangeValueForKey:,如有必要,请检查并发送我的通知,然后调用超级实现。但是在文档中明确禁止这样做:

  

didChangeValueForKey:

     

调用以通知接收者给定属性的值已更改。

     

- (void)didChangeValueForKey:(NSString *)key

     

参数

     

     

更改的媒体资源的名称。讨论有关详细信息,请参阅   键值观察编程指南。

     

您不得覆盖此方法。

那么,我该怎么办?

3 个答案:

答案 0 :(得分:1)

我刚刚阅读了相同的文档,但如果您查看NSManagedObject文档的顶部,它实际上会说"您强烈反对..."

我想这完全取决于您的实施细节。例如,我在可以在本地修改的数据模型上执行以下操作,并与服务器同步:

- (void)didChangeValueForKey:(NSString *)key
{
    [super didChangeValueForKey:key];  // MUST CALL THIS!

    if ([key isEqualToString:NSStringFromSelector(@selector(name))] ||
        [key isEqualToString:NSStringFromSelector(@selector(text))] ||
        [key isEqualToString:NSStringFromSelector(@selector(filename))]
        )
    {
        self.lastModified = [NSDate date];
    }
}

我不确定为什么这会被认为是坏事。它只是说"做你通常做的事情。另外,我想设置另一个依赖于这种变化的属性。"

答案 1 :(得分:0)

您想要的是关键价值观察。您应该能够注册该特定密钥,并在更改时收到通知。也请查看:Using KVO to observe changes to a property on an object inside a collection in Objective-C

答案 2 :(得分:0)

我通过创建一个单独的对象(我用来管理我的核心数据堆栈的单例)来解决这个问题。所有自我观察的复杂性现在已经消失,我不需要担心在awakeFromFetch上添加或删除观察者等等。