核心数据 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
直接从持久存储中删除大量对象。这适用于某些对象,但不适用于其他对象,我认为这与我的人际关系有关。
我有一个由Subject
和Course
组成的对象图,其中存在一对多关系。受试者可以拥有任意数量的课程。
Subject
上存在“课程”关系,删除规则为 Cascade
,因为我希望在删除 subject
时删除与 subject
关联的所有课程。
相反的是Course
上的“主题”,删除规则为Nullify
。在这里,我对苹果对Nullify
的描述有点困惑:
删除对象之间的关系,但不要删除任何一个对象。 仅当员工的部门关系是可选的,或者您确保在下一次保存操作之前为每个员工设置了新部门时,这才有意义。
这很清楚,但为什么要删除关系而不删除任何一个对象?如果我删除Course
,我希望删除Course
,并删除从subject
到course
的关系,以便删除的Course
的故障不会出现在@ 987654337@ 上Subject
的courses
设置。
我想提供一种删除实体中所有对象的方法。当我通过单独获取和删除每个 course
来尝试此操作时,courses
被正确删除并从 courses
上的 courses
的 NSSet
中删除。
由于我不知道会出现多少courses
,并且我想确保在每种情况下都具有高性能,所以我想我会使用批量删除来删除所有courses
。问题是,虽然利用NSBatchDeleteRequest
删除所有Subjects
工作正常,但删除所有courses
(因为Cascade
规则),尝试使用此方法删除所有Courses
似乎留下所有对象到位。
我使用NSBatchDeleteRequest
删除所有Courses
,但是当我查询MOC
以查看Subjects
和Courses
仍然存在时,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 时冻结