如何向Core Data指示对象已更改?

时间:2014-01-25 01:09:22

标签: ios objective-c cocoa-touch core-data ios7

在我的CoreData模型中,我有一个名为Contact的实体。它有一个名为profileImage的属性,其类型设置为Transformable。

在Contact类(NSManagedObject的子类)中,我将profileImage从通用id更改为UploadedImage:

@property (nonatomic, retain) UploadedImage * profileImage;

UploadedImage类有一些属性。

问题是CoreData不知道UploadedImage对象的属性何时发生了变化。如果仅更改了这些属性,则在保存托管对象时,永远不会在Contact对象上调用willSave方法。如果我更改Contact对象上的任何其他属性,它将按预期工作:它只是“看不到”Contact对象中UploadedImage对象上的任何内容的更改。

指示需要保存托管对象的正确方法是什么?我应该在我的Contact对象上手动调用willChangeValueForKey:didChangeValueForKey:来获取密钥'profileImage'吗?

修改以澄清一些事情

  • Contact是CoreData实体,但ImageUpload类不是。
  • CoreData 保存在ImageUpload对象中的数据(因为我实现了NSCoding协议方法,我认为)。如果我更改ImageUpload对象上的属性,并更改Contact对象上的属性,则会保存Contact,并且当从CoreData再次加载Contact时,该更改的值将保留在ImageUpload对象上。

3 个答案:

答案 0 :(得分:3)

除非我不了解另一种方式,否则听起来就像标记NSManagedObject一样脏。您可以使用单独的dirtyFlag属性,或仅使用profileImage属性本身来执行此操作。

自动化的一种方法是KVO。您会在UploadedImage类中观察Contact的所有属性,然后只需调用self.profileImage = self.profileImage。我不确定这是否由编译器优化。如果是,您还可以拨打willChangeValueForKey:didChangeValueForKey:,这应该会触发它。如果Core Data发现该对象实际上没有更改,您可以尝试实施NSCopying并分配原始UploadedImage的副本。

答案 1 :(得分:0)

我不认为Core Data会持续对子类进行更改。 Core数据中的合同位于父实体和Core Data之间,因此Core Data仅响应对实体类中的属性所做的更改。

您可以通过在实体中将该属性设置为NSDictionary并在子类中将图像对象添加到字典中来解决此问题。

答案 2 :(得分:0)

扩展Scott的解决方案(无需复制!),这是一种适用于任何字段的Swift方法:

static func markDirty<C, T>(_ obj: C, _ keyPath: ReferenceWritableKeyPath<C, T>) {
    obj[keyPath: keyPath] = obj[keyPath: keyPath]
}

使用方式如下:

NSManagedObject.markDirty(playlist, \.rules)

不幸的是,由于泛型的限制,现在无法将其定义为实例方法。