核心数据 changedValues 是不是忽略二进制数据和转换后的属性?

Posted

技术标签:

【中文标题】核心数据 changedValues 是不是忽略二进制数据和转换后的属性?【英文标题】:Does core data changedValues ignore binary data and transformed attributes?核心数据 changedValues 是否忽略二进制数据和转换后的属性? 【发布时间】:2014-02-28 21:01:03 【问题描述】:

在保存上下文之前,我正在通过changedValues 评估核心数据实体,以便对托管对象进行一些额外的更改。就我而言,我有一些重要的计算,只有在对象真正改变时才相关。

我将我的一个属性更改为二进制数据,并添加了一个转换器来存储字典数据。 changedValues 方法总是返回一个 nil 字典或没有这个属性的字典。

文档中的ChangedValues:

返回值 一个字典,其中包含自上次获取或保存接收器以来已更改的持久属性的名称作为键,以及属性的新值作为值。

讨论 此方法仅报告对定义为接收器的持久属性的属性的更改,而不是对瞬态属性或自定义实例变量的更改。此方法不会引发不必要的关系错误。

changedValues 不返回转换后属性的值吗?当我存储图像之类的东西时,我已经看到 changedValues 返回字典中的二进制数据属性名称。

我在文档中没有找到关于字典中返回的有效实体属性的信息。

确定托管对象是否已被修改的最佳做法是什么?

谢谢!

更新: 这是我用来将字典存储为二进制对象的转换器:

@implementation DictionaryToData
+ (BOOL)allowsReverseTransformation

    return YES;


+ (Class)transformedValueClass 
    return [NSDictionary class];


- (id)transformedValue:(id)value 
    return [NSKeyedArchiver archivedDataWithRootObject:value];


- (id)reverseTransformedValue:(id)value 
    return [NSKeyedUnarchiver unarchiveObjectWithData:value];


@end

【问题讨论】:

我希望它包含每个属性,无论类型如何。您能否添加一些关于您正在转换哪些数据以及如何执行此操作的信息? @Tom,我为我的变压器添加了代码。没什么花哨的,只是 NSDictionary 到/从二进制数据。有趣的是,我检查了托管对象的 isUpdated 属性并设置了它。 @Tom,我检查了托管对象的 isUpdated 属性并设置了它。另一个奇怪的观察是,通过这个转换器更改属性也不会被我的 undoManager 使用。 好的,作为测试,我移除了转换器并自己使用 NSKeyedArchiver、NSKeyedUnarchiver 将数据转换为核心数据/从核心数据转换。现在核心数据知道了变化,我的撤消管理器再次工作。这是没有意义的,我找不到这种行为的文档。谁能证实这一点? 我知道转换器可能失败的唯一原因是字典是否包含不可归档的对象(即不符合NSCoding 的对象)。假设您两次都使用相同的数据,那么手动存档也会失败。 【参考方案1】:

NSDictionary 不能包含二进制文件。您必须单独获取二进制文件(而不是在字典中)并手动转换它。

【讨论】:

NSDictionary 可以包含任何对象,例如NSData 嗯,我昨天刚读到这个。与字典相关的东西不能包含 NSData。我会调查的,因为我一定混淆了指令。 @DSMagic,我在将 NSDictionary 转换为二进制数据/从二进制数据转换时没有遇到问题。我的问题是核心数据没有将其列为修改后的属性,使用 changedValues 在通过转换器更改属性时获取更改值的字典。【参考方案2】:

在实现访问器时,您需要围绕原始访问调用 willAccessValueForKey:didAccessValueForKey:

同样,在实现 setter 时,您需要在原始 setter 周围调用 willChangeValueForKey:didChangeValueForKey:

【讨论】:

这是对的,但与价值转换器的问题完全无关。 我补充说,因为NSDictionary 符合NSCoder,这意味着您根本不需要自定义转换器......并且OP 提供的代码是有效的转换器实现。所以,它一定是别的东西......如果它是一个有效的字典,不获取changedValues 的一种方法是有一个自定义的setter 实现,而忘记调用KVC willChange/didChange 方法。可能应该是评论而不是答案。

以上是关于核心数据 changedValues 是不是忽略二进制数据和转换后的属性?的主要内容,如果未能解决你的问题,请参考以下文章

NSManagedObject changedValues 不正确

MySQL高级篇-容易忽略的核心内容变量

Java被忽略的基本知识

核心数据:对多谓词被忽略

NSInMemoryStoreType 类型的核心数据忽略实体的约束

核心数据和 NSFetchedResultsController:忽略 controllerDidChangeContent 中的字段