使用NSPrivateQueueConcurrencyType的KVO

时间:2013-01-07 20:28:37

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

我想确定核心数据中的属性是否已更改并更新我的UI。作为在NSPrivateQueueConcurrencyType类型的托管对象上下文中运行的后台提取的结果,该属性可能会更改。

我添加了一个监听器:[myCoreDataEntity addObserver:self forKeyPath:myCoreDataAttribute options:NSKeyValueObservingOptionNew context:nil]

但事件永远不会发生。知道为什么吗?对象在另一个上下文中被更改 - 这可能是原因吗? (当保存:在父上下文中完成时,什么都不会触发)。

我可以使用手动KVO,但由于该对象尚未保存到父上下文,因此刷新UI不起作用,因为当在与NSPrivateQueueConcurrencyType相关联的上下文中更改对象时,它指向NSMainQueueConcurrencyType中的上下文/ p>

2 个答案:

答案 0 :(得分:1)

假设您的示例中的myCoreDataEntity是托管对象,问题是对于已建模的属性1,[托管对象的核心数据]已禁用自动外部更改通知:

  

NSManagedObject禁用建模属性的自动键值观察(KVO)更改通知,并且原始访问器方法不会调用访问和更改通知方法。对于未建模的属性,在OS X v10.4上,Core Data也会禁用自动KVO;在OS X v10.5及更高版本中,Core Data采用了NSObject的行为。

您可以turn them开启特定属性,或托管对象子类中的所有属性或托管对象子类的类别:

单一财产:

- (BOOL) automaticallyNotifiesObserversFoMyCoreDataAttribute {
    return YES;
}

所有属性(不推荐):

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)theKey {
    return YES;
}

它不发送自动更改通知的原因主要是性能。自动更改通知确实增加了一些开销,但在最近的硬件上,即使使用数千个对象,它也相当小。与往常一样,了解哪些内容适合您。

答案 1 :(得分:0)

您没有收到通知,因为您正在观察错误的对象。 NSEntityDescription在运行时永远不会更改。它表示实体在数据模型中的定义方式。但是,使用实体描述的NSManagedObject实例可以在运行时进行更改。如果您想知道特定托管对象上的属性是否已更改,则需要观察该特定对象。

如果您需要在任何任何托管对象更改该属性的值时收到通知,您最好的选择是为该属性编写自定义setter并在那里处理它。您可能还会发现NSManagedObjectContextObjectsDidChangeNotification有用,但会触发任何属性更改。