在我的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'吗?
修改以澄清一些事情
NSCoding
协议方法,我认为)。如果我更改ImageUpload对象上的属性,并更改Contact对象上的属性,则会保存Contact,并且当从CoreData再次加载Contact时,该更改的值将保留在ImageUpload对象上。答案 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)
不幸的是,由于泛型的限制,现在无法将其定义为实例方法。