核心数据 NSBatchDeleteRequest 似乎将对象留在上下文中

Posted

技术标签:

【中文标题】核心数据 NSBatchDeleteRequest 似乎将对象留在上下文中【英文标题】:Core Data NSBatchDeleteRequest appears to leave objects in context 【发布时间】:2015-11-04 23:04:11 【问题描述】:

我在 Core Data 中看到了很多关于批量删除的问题,但似乎没有一个能解决我的问题。

我正在使用 Core Data 创建一个 ios 9 / Swift 应用程序。在今年的 WWDC 上,我参加了 Core Data 会议,发现我可以使用 NSBatchDeleteRequest 直接从持久存储中删除大量对象。这适用于某些对象,但不适用于其他对象,我认为这与我的人际关系有关。

我有一个由SubjectCourse 组成的对象图,其中存在一对多关系。受试者可以拥有任意数量的课程。

Subject 上存在“课程”关系,删除规则为 Cascade,因为我希望在删除 subject 时删除与 subject 关联的所有课程。

相反的是Course 上的“主题”,删除规则为Nullify。在这里,我对苹果对Nullify的描述有点困惑:

删除对象之间的关系,但不要删除任何一个对象。 仅当员工的部门关系是可选的,或者您确保在下一次保存操作之前为每个员工设置了新部门时,这才有意义。

这很清楚,但为什么要删除关系而不删除任何一个对象?如果我删除Course,我希望删除Course,并删除从subjectcourse 的关系,以便删除的Course 的故障不会出现在@ 987654337@ 上Subjectcourses 设置。

我想提供一种删除实体中所有对象的方法。当我通过单独获取和删除每个 course 来尝试此操作时,courses 被正确删除并从 courses 上的 coursesNSSet 中删除。

由于我不知道会出现多少courses,并且我想确保在每种情况下都具有高性能,所以我想我会使用批量删除来删除所有courses。问题是,虽然利用NSBatchDeleteRequest 删除所有Subjects 工作正常,但删除所有courses(因为Cascade 规则),尝试使用此方法删除所有Courses 似乎留下所有对象到位。

我使用NSBatchDeleteRequest 删除所有Courses,但是当我查询MOC 以查看SubjectsCourses 仍然存在时,Courses 仍然返回并且Subject 拥有他们仍然有对他们的引用。

相比之下,当我单独获取和删除每个Course 时,我随后的获取正确地为所有Courses 显示一个空数组,并且Subject 上的“课程”关系似乎已被正确修改。

是的,我在执行请求后保存上下文。我想可能不会通知上下文商店的功能,但是再次删除所有subjects 效果很好。这是怎么回事?

【问题讨论】:

批量删除无视删除规则。 ***.com/questions/32915874/… 【参考方案1】:

the WWDC 2015 session which describes NSBatchDeleteRequest 解释说“更改未反映在上下文中”。所以你看到的是正常的。批量更新直接在持久存储文件上工作,而不是通过托管对象上下文,因此上下文不知道它们。当您通过获取然后删除来删除对象时,您正在处理上下文,因此它知道您正在进行的更改(实际上它正在为您执行这些更改)。

如果您使用NSBatchDeleteResultTypeObjectIDs,您可以使用mergeChangesFromRemoteContextSave:intoContexts: 将批量删除的结果合并回您的上下文中以更新您的上下文。如果您没有从上下文加载任何其他托管对象,您也可以使用reset

【讨论】:

谢谢!我使用了重置,它起作用了。在看到您的答案之前,我确实看到 SQLite 数据库中缺少 Courses 并且应用程序在重新启动时反映了这一点。 为了安全起见,我想切换到 mergeChanges 方法。我有一份批量删除结果的副本,我已将其设置为NSBatchDeleteResultTypeObjectID。我在mergeChangesFromRemoteContextSave 上为changeNotificationData: [NSObject: AnyObject] 传递什么? 好吧,我没有使用NSBatchDeleteResultTypeObjectID,而是注册了NSManagedObjectContextDidSaveNotification,并从区块中调用了mergeChangesFromRemoteContextSave @MatthewS 这对你有用吗?根据不应该工作的文档和会话视频(WWDC 2015)。批量删除请求绕过托管对象上下文,这意味着不会发送任何反映批量删除请求所做更改的通知。 @BartJacobs 是的,这对我有用。使用这种通知观察方法,这些变化似乎反映在上下文中。可能是因为我直接在我的上下文实例上调用executeRequest【参考方案2】:

我最终添加了以下内容来处理批量删除后的上下文。

[self.managedObjectContext refreshAllObjects];

【讨论】:

这不行

以上是关于核心数据 NSBatchDeleteRequest 似乎将对象留在上下文中的主要内容,如果未能解决你的问题,请参考以下文章

如何设置 NSBatchDeleteRequest 的 NSBatchDeleteResult 类型?

使用带有 NSBatchDeleteRequest 的 NSFetchedResultsController

UI 在执行 NSBatchDeleteRequest 时冻结

NSBatchDeleteRequest 留下不好的关系

如何让 NSBatchDeleteRequest 删除并允许您再次添加回对象

大数据核心技术都有哪些