10

在 WWDC15 视频会话中,“核心数据的新功能”在 10:45 分钟(进入演示文稿)中,Apple 工程师描述了模型构建器的一项新功能,该功能允许您指定独特的属性。一旦你设置了这些独特的属性,Core Data 将不会创建具有该属性的重复对象。这是为了消除在创建新对象之前检查是否相同对象的需要。

我一直在对此进行试验,但没有运气阻止创建具有相同“独特”属性(重复对象)的新对象。除了 5 分钟的视频解释外,我没有找到任何其他说明如何使用此功能的信息。

在此处输入图像描述

有没有人有在核心数据模型中实现“唯一”属性的经验?

4

2 回答 2

12

简短回答: 您需要将此行添加到您的核心数据堆栈设置代码中:

managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy

长答案:我为此苦苦挣扎了一段时间,但我想我现在已经弄清楚了:

唯一约束 (UC) 不会阻止在上下文中创建重复项。只有当您尝试保存该上下文时,Core Data 才会检查 UC 的唯一性。

如果它为 UC 找到多个具有相同值的对象,则默认行为是抛出错误,因为冲突的默认合并策略是NSErrorMergePolicyType. 该错误包含其 中的冲突对象userInfo.conflictList,因此您可以手动解决冲突。

但大多数时候,您可能希望使用其他合并策略之一,并让 Core Data 自动合并冲突。这些合并策略之前确实存在,它们用于不同上下文中对象之间的冲突。也许这就是为什么在 WWDC Session 220 的 UC 功能的上下文中没有提到它们的原因。通常正确的选择是NSMergeByPropertyObjectTrumpMergePolicy. 它基本上说“新数据胜过旧数据”,这是您在从外部源导入新数据时在常见场景中想要的。

(提示:首先我在验证这种行为时遇到了问题,因为重复的对象似乎保留在上下文中,直到保存操作完成 - 在我的情况下,这在后台队列中异步发生。所以如果你在点击后立即获取/计数你的对象保存按钮,您可能仍会看到重复项。)

于 2015-08-24T00:23:54.697 回答
0

我不知道正确的答案,因为这是一个测试版,但在玩了一分钟后,我找到了一种让它工作的方法:

  1. 告诉模型哪些属性形成了唯一约束,正如您在问题中的图像所示。

  2. 添加新记录:

let newTag = NSEntityDescription.insertNewObjectForEntityForName("Tag", inManagedObjectContext: context) as! Tag
  1. 将值分配给属性。

  2. 保存您的更改:

do {
  try context.save()
} catch let error as NSError {
  print("Error: \(error.localizedDescription)")
  context.reset()
}

钥匙在catch方块里。如果发生错误,请将上下文重置为之前的状态。由于保存操作失败,重复记录将不存在。

请注意,您应该检查错误是否是由重复记录引起的。

我希望这有帮助。

于 2015-07-10T10:58:49.580 回答