带有 NSPrivateQueueConcurrencyType 的 KVO

Posted

技术标签:

【中文标题】带有 NSPrivateQueueConcurrencyType 的 KVO【英文标题】:KVO with NSPrivateQueueConcurrencyType 【发布时间】:2013-01-07 20:28:36 【问题描述】:

我想确定核心数据中的某个属性是否发生更改并更新我的 UI。该属性可能会因在 NSPrivateQueueConcurrencyType 类型的托管对象上下文中运行的后台提取而改变。

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

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

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

【问题讨论】:

【参考方案1】:

您没有收到通知,因为您观察到了错误的对象。 NSEntityDescription 在运行时从不改变。它代表了实体在数据模型中的定义方式。不过,使用实体描述的NSManagedObject 的实例可以并且确实在运行时发生变化。如果您想知道特定托管对象的属性是否发生变化,则需要观察该特定对象。

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

【讨论】:

谢谢,汤姆。我的描述不够清楚。我写了 myCoreDataEntity,但打算写 myManagedObject。真丢人! NSManagedObject 属性更新也不会触发事件。自定义设置器是一个很好的方法。感谢您的提示。【参考方案2】:

假设您的示例中的myCoreDataEntity 是一个托管对象,那么问题在于建模属性1 的自动外部更改通知[被托管对象的Core Data 禁用]:

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;

它不发送自动更改通知的原因主要是性能。自动更改通知确实增加了一些开销,尽管在最近的硬件上它相当小,即使在处理数千个对象时也是如此。与往常一样,配置文件以查看适合您的方法。

【讨论】:

这不是很清楚,但尽管 NSManagedObject 禁用自动 KVO 是正确的,但在 NSManagedObject 的建模属性的动态方法中,它手动调用 willChangeValueForKey、didChangeValueForKey,因此在建模属性上使用 KVO 可以正常工作。此答案中的更多信息:***.com/a/3728567/259521

以上是关于带有 NSPrivateQueueConcurrencyType 的 KVO的主要内容,如果未能解决你的问题,请参考以下文章

带有和不带有聚合的 sql 查询

如何翻转正面带有标签而背面带有另一个标签的视图 - 参见图片

CakePHP 如何处理带有/不带有 'id' 字段的 HABTM 表?

带有滚动的 Div 和带有绝对位置的内容

带有 RecyclerView 的 DialogFragment 比带有 Recyclerview 的 Fragment 慢

访问控制允许带有和不带有 www 的来源