检测对NSManagedObject的特定属性的更改

Jam*_*ton 21 iphone notifications core-data nsmanagedobject

如何检测对特定属性的更改NSManagedObject?在我的核心数据数据模型中,我有一个Product代表待售产品的实体.该Product实体有几个属性:price,sku,weight,numberInStock,等每当price一个属性Product的变化,我需要执行冗长的计算.因此,我想知道任何更改的price属性,[编辑]即使该更改来自合并另一个线程上保存的上下文.这样做的好方法是什么?我的商店里有成千上万的物品; 显然,向每个人发送一条消息是不可行的. ProductProductaddObserver

我一直用NSManagedObjectContextObjectsDidChangeNotification检测的变化,但它只是通知我一个管理对象发生了变化,而不是该对象的属性发生变化.每当a发生任何变化时,我都可以重做计算Product,但只要不相关的属性发生变化,就会导致无用的重新计算.我正在考虑创建一个Price实体(只包含一个price属性)并使用Product和之间的一对一关系Price.这样,我可以检测到Price对象的更改,以便开始计算.这对我来说似乎过于愚蠢.有没有更好的办法?

更新:

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

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

rai*_*ade 41

关于这个帖子的一点,

Core Data生成的NSManagedObjectContextObjectsDidChangeNotification指示托管对象已更改,但未指示哪个属性已更改.

它确实如此."changedValues"方法可用于查询更改的属性.

就像是,

 if([updatedObjects containsKindOfClass:[Config class]]){
    //if the config.timeInterval changed
    NSManagedObject *obj = [updatedObjects anyObject];
    NSDictionary *dict=[obj changedValues];
    NSLog(@"%@",dict);
    if([dict objectForKey:@"timeInterval"]!=nil){
      [self renderTimers];
    }
  }
Run Code Online (Sandbox Code Playgroud)

  • 因此,我从`NSManagedObjectContextObjectsDidChangeNotification`获取更新的对象集.然后,为了找出每个更新的`NSManagedObject`的变化,我只需查看该对象的`changedValues`字典.真棒!它没有解决跨线程合并问题 - 当合并保存在后台线程上的上下文时,`NSManagedObjectContextObjectsDidChangeNotification`只包括对主线程上下文中当前对象的更改 - 但它绝对是一个超级有用的方法,我可以在很多其他地方使用.谢谢,@ rarawayparade! (2认同)
  • 也看看`changedValuesForCurrentEvent` (2认同)

Tec*_*Zen 10

这种情况是您需要自定义NSManagedObject子类的地方.您需要子类,因为您要向管理对象添加对价格更改做出反应的行为.

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

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

只需添加代码来处理价格变化,您就完成了.只要特定产品的价格发生变化,代码就会运行.