检测对NSManagedObject的特定属性的更改 [英] Detecting changes to a specific attribute of NSManagedObject

查看:185
本文介绍了检测对NSManagedObject的特定属性的更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何检测对 NSManagedObject 的特定属性的更改?在我的核心数据数据模型中,我有一个产品实体,表示要销售的产品。 产品实体有几个属性: price sku weight a 产品更改,我需要执行冗长的计算。因此,我想知道任何 产品价格 strong>即使该更改来自合并保存在另一个主题上的上下文。什么是一个好的办法去做这个?我在我的商店有成千上万的产品对象;显然不可能发送每个 addObserver 消息。

How can I detect changes to a specific attribute of an NSManagedObject? In my Core Data data model, I have a Product entity that represents a product for sale. The Product entity has several attributes: price, sku, weight, numberInStock, etc. Whenever the price attribute of a Product changes, I need to perform a lengthy calculation. Consequently, I would like to know when the price attribute of any Product changes, [edit] even if that change comes from merging a context saved on another thread. What is a good way to go about doing this? I have thousands of Product objects in my store; obviously it's not feasible to send each one an addObserver message.

我一直使用 NSManagedObjectContextObjectsDidChangeNotification 来检测更改,但它只会通知我托管对象已更改,而不是该对象的属性已更改。只要有<$>任何更改为产品,我就可以重做计算,但是当不相关的属性更改时,会导致无用的重新计算。我正在考虑制定一个 Price 实体(只包含价格属性),并使用一对一关系产品价格。这样,我可以检测对 Price 对象的更改,以启动计算。这看起来对我来说太荒谬了。有更好的方法吗?

I have been using NSManagedObjectContextObjectsDidChangeNotification to detect changes, but it only notifies me that a managed object has changed, not which attribute of that object has changed. I could redo the calculation whenever there's any change to a Product, but that results in useless recalculations whenever an irrelevant attribute has changed. I'm considering making a Price entity (that only contains a price attribute) and using a to-one relationship between Product and Price. This way, I can detect changes to Price objects in order to kick off the calculation. This seems excessively kludgy to me. Is there a better way?

更新:

@railwayparade指出我可以使用 NSManagedObject changedValues 方法来确定每个更新的对象的哪些属性已更改。我完全错过了这个方法,它将完全解决我的问题,如果更改不是在后台线程并合并到主线程的上下文。 (见下一段。)

@railwayparade pointed out that I could use the changedValues method of NSManagedObject to determine which properties have changed for each updated object. I completely missed that method, and it would totally solve my problem if the changes weren't being made on a background thread and merged into the main thread's context. (See next paragraph.)

我完全错过了关于 NSManagedObjectContextObjectsDidChangeNotification 工作方式的一个细微之处。据我所知,当另一个线程上保存的托管对象上下文合并到主线程上的上下文(使用 mergeChangesFromContextDidSaveNotification:)时,生成的 NSManagedObjectContextObjectsDidChangeNotification 仅包含当前在主线程的受管对象上下文中的对象的更改信息。如果更改的对象不在主线程的上下文中,它不会成为通知的一部分。这是有道理的,但不是我期待的。因此,我想使用一对一关系而不是一个属性来获得更详细的更改信息实际上需要检查后台线程的 NSManagedObjectContextDidSaveNotification ,而不是主线程的 NSManagedObjectContextObjectsDidChangeNotification 。当然,简单地使用 NSManagedObject changedValues 方法作为@railwayparade有帮助地指出会更加聪明。然而,我仍然留下的问题,主线程上合并的更改通知不一定包含在后台线程上所做的所有更改。

I completely missed a subtlety about the way that NSManagedObjectContextObjectsDidChangeNotification works. As far as I can tell, when a managed object context saved on another thread is merged into a context on the main thread (using a mergeChangesFromContextDidSaveNotification:), the resulting NSManagedObjectContextObjectsDidChangeNotification only contains change information about objects that are currently in the main thread's managed object context. If a changed object isn't in the main thread's context, it won't be part of the notification. It makes sense, but wasn't what I was anticipating. Therefore, my thought of using a to-one relationship instead of an attribute in order to get more detailed change information actually requires examination of the background thread's NSManagedObjectContextDidSaveNotification, not the main thread's NSManagedObjectContextObjectsDidChangeNotification. Of course, it would be much smarter to simply use the changedValues method of NSManagedObject as @railwayparade helpfully pointed out. However, I'm still left with the problem that the change notification from the merge on the main thread won't necessarily contain all of the changes made on the background thread.

推荐答案

这种情况是你需要一个自定义的NSManagedObject子类。您需要子类,因为您要对托管对象添加一个行为,对价格变化做出反应。

This type of circumstance is where you need a custom NSManagedObject subclass. You need the subclass because you are adding a behavior, reacting to a price change, to the managed object.

在这种情况下,您将覆盖 price 属性的访问器。使用数据模型编辑器中的弹出菜单创建自定义子类。然后选择 price 属性,并选择将Obj-C 2.0实现复制到剪贴板。它会给你很多东西,但关键点将是这样:

In this case, you would override the accessor for the price attribute. Create a custom subclass using the popup menu in the data model editor. Then select the price attribute and choose 'Copy Obj-C 2.0 Implementation to the Clipboard`. It will give you a lot of stuff but the key bit will look like this:

- (void)setPrice:(NSNumber *)value 
{
    [self willChangeValueForKey:@"price"];
    [self setPrimitivePrice:value];
    [self didChangeValueForKey:@"price"];
}

只需添加代码来处理价格变化即可。每当特定产品的价格变化时,代码将运行。

Just add the code to deal with the price change and you are done. Anytime a specific product's price changes, the code will run.

这篇关于检测对NSManagedObject的特定属性的更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆