是否可以禁用特定Core Data保存的级联删除?

时间:2015-04-23 18:28:59

标签: ios objective-c core-data nsmanagedobjectcontext

问题:

当有NSManagedObjectContext要处理时,当您在deletedObjects上调用保存时,它会执行大量工作来跟踪关系以确定哪些相关对象也需要删除。这是通过每次保存完成的(即使在父/子上下文的情况下),如果我知道我将通过这些父上下文保存,我希望能够在第一个上下文之后跳过此检查但是,我无法找到这样做的机制。

背景:

情况如此,我有3个背景:

  • C(B的子上下文):用于执行工作的后台线程上下文
  • B(A的子上下文):主线程上下文,用于我的获取结果控制器,UI访问
  • A(持久存储的子节点):用于保存到磁盘的后台线程上下文

我的对象图是" Rich"并且一些关系是针对具有100,000多个项目的表。正因为如此,缺失是可以理解的慢(级联删除删除一个数与每个根对象删除对象)...分析性能然而,当我意识到它' S实际上有很多慢于它需要,在保存大部分CPU /时间用于解析图中的关系(试图找出哪些相关对象也需要删除)...并且它重复这个过程每次保存,即使我节省了通过。
示例保存过程:

  • 上下文C有1个已删除的对象
  • 保存上下文C - > B(大约1秒的工作正在跟踪关系)
  • 现在保存了上下文C(0个已删除的对象),上下文B包含原始删除的对象,还有30个新的相关对象也需要删除(31个对象)
  • 保存背景B - > A(大约1秒的工作重新检查这些关系,这是我想跳过的工作)
  • 上下文B已保存(0个已删除的对象),上下文A具有与B必须删除的相同的31个对象
  • 保存上下文A - >持久存储(轻松工作,似乎这一步不会再次检查)

我尝试了继承并查看-[NSManagedObject validateForDeletion]-[NSManagedObjectContext processPendingChanges]但没有运气。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

如果您使用多个核心数据堆栈,并且您不介意进入一些中等复杂的代码,则应该可以有选择地启用/禁用删除规则。您将最终得到多个托管对象上下文,其中一些具有规则,而另一些则没有。这笔交易是:

  • 首次加载NSManagedObjectModel时,[NSRelationshipDescription versionHash]是可变的,因此您可以在代码中修改模型,只要您不进行使其与持久性存储不兼容的更改(这将需要迁移)。
  • 模型兼容性仅由影响数据保存到持久性存储的方式的详细信息确定。 不包含删除规则,因此无需迁移即可对其进行修改。 (请参阅NSManagedObjectModel的文档,了解影响兼容性的内容。
  • NSManagedObjectModel的实例只有在您使用持久存储之后才可变,因此您必须在加载任何数据之前进行更改。这意味着如果您希望在某些情况下删除规则而在其他情况下不需要删除规则,则需要NSManagedObjectModel的不同实例。

因此,如果您创建完全独立的Core Data堆栈(NSPersistentStoreCoordinatorNSManagedObjectModel等所有内容的单独实例),您可以将一个堆栈配置为不具有这些删除规则,但将它们留在原位其他。由于删除规则不会影响模型哈希,因此它们仍然是兼容的。

您无法使用父/子托管对象上下文执行此操作,因为根据定义它们是同一Core Data堆栈的一部分。

要删除或更改删除规则,您必须从entities的实例开始。获取模型中的relationshipsByName,然后获取您感兴趣的实体的NSRelationshipDescription。最后,在deleteRule上,将NullifyDeleteRule更改为您想要的任何内容(可能{在这种情况下{1}}。

这有点复杂,但应该有效。

顺便说一句,我有兴趣了解您的绩效分析所显示的更多细节。