Ios NSManagedObject';s hasChanges为true,而changedValue为空

Ios NSManagedObject';s hasChanges为true,而changedValue为空,ios,macos,core-data,nsnotificationcenter,Ios,Macos,Core Data,Nsnotificationcenter,我试图观察NSManagedObject上的单个NSManagedObjectContextWillSaveNotification更改: - (void)managedObjectContextWillSave:(NSNotification *)notification { for (NSManagedObject * object in self.mutableObservedManagedObjects) { if (object.hasChanges)

我试图观察
NSManagedObject
上的单个
NSManagedObjectContextWillSaveNotification
更改:

- (void)managedObjectContextWillSave:(NSNotification *)notification
{
    for (NSManagedObject * object in self.mutableObservedManagedObjects)
    {
        if (object.hasChanges)
        {
            [self managedObjectWasUpdated:object];
        }
    }
}
问题是
hasChanges
为true,而
对象.changedvalue
为空,因此错误地触发
managedobjectwasdupdated:

我试图理解为什么会出现这种情况,以及在调用
managedobjectwasdupdated:
之前是否最好检查
object.changedValues.count



isInserted
isDeleted
均为false。

根据文档,如果接收器已插入、已删除或未保存更改,则
hasChanges
将返回YES,否则返回NO


在您的情况下,您可以检查
isInserted
isUpdated
isDeleted
标志以查找托管对象发生了什么<代码>更改值仅显示自上次获取或保存接收器以来已更改的属性。

我遇到了相同的问题。我没有获取标志,而是检查changedValues()是否为空

对于Swift:

if !managedObject.changedValues().isEmpty {
    // Has some changed values
}

您的实体上有任何瞬态属性吗?我看到了您描述的行为,我编写了一些测试代码,显示修改瞬态属性会导致
hasChanges
返回
true
,而
changedvalue
为空


通过使用
setPrimitiveValue:forKey:
修改瞬态属性或核心数据生成的等效方法(
setPrimitiveFoo:
用于名为
foo
的属性),可以避免这种行为。您还可以实现瞬态属性的setter来为您执行此操作。

根据我的经验,如果实体已经存在,则加载它,然后将一个值设置为等于其先前值的属性,然后记录将被标记为已更新,
hasChanges
将返回
YES
,而
changedvalue
将为空。在保存上下文时,更新的是一个称为Z_OPT的特殊核心数据列,它表示实体已更新的次数。对于这些情况,您可以在保存之前执行以下操作:

for (NSManagedObject *managedObject in context.updatedObjects.objectEnumerator) {
    if (!managedObject.changedValues.count) {
        [context refreshObject:managedObject mergeChanges:NO];
    }
}

为了不更新Z_OPT值。

在iOS 7中,您还可以使用hasPersistentChangedValue而不是ChangedValue。我认为这表现得更好。

我遵循了文档,并且
被插入
/
被删除
都是错误的,
被更新
是正确的,但没有
更改值
。这是有效的,但仍然没有文档记录的行为,让人怀疑苹果什么时候会打破它……:(我相信这是最准确的答案。
hasChanges
是基于核心数据所知道的一切(包括Z_OPT)。
changedValues()
是实体的不同报告字段。在大多数情况下,应用程序可能更关心
changedValues().isEmpty
。您可以使用在
NSManagedObject
上引入的新属性来代替检查
ChangedValue.count
var hasPersistentChangedValue:Bool
不幸的是
[NSManagedObjectContext-hasChanges]
仍将是
true
确实
hasPersistentChangedValue
是最佳选择。根据头文件的注释,
hasPersistentChangedValue
如果任何持久属性未将
isEqual
与其上次保存的状态进行比较,则返回YES。不会不必要地触发关系错误。此dif来自现有
-hasChanges
方法的FER,该方法是一个简单的脏标志,还包括瞬态属性。