核心数据NSBatchDeleteRequest似乎将对象留在上下文中 [英] Core Data NSBatchDeleteRequest appears to leave objects in context
问题描述
我已经看到许多有关Core Data中批量删除的问题,但是似乎没有一个问题可以解决我的问题。
我正在使用Core Data创建iOS 9 / Swift应用。在今年的WWDC上,我参加了Core Data会议,发现可以使用 NSBatchDeleteRequest
直接从持久性存储中删除大量对象。这适用于某些对象,但不适用于其他对象,我认为这与我的关系有关。
我有一个包含主题
和课程
,那里存在一对多的关系。主题可能拥有他们想要的任意多的课程。
主题
有一个课程关系,但有一个删除级联
的规则,因为我希望在时删除与
被删除。主题
相关的所有课程主题
在 Course
上逆是'subject',带有一个删除 Nullify
的规则。在这里,我对Apple对 Nullify
的描述感到有些困惑:
删除对象之间的关系,但不要删除任何一个对象。
仅当雇员的部门关系是可选的,或者您确保在下一次保存操作之前为每个雇员设置一个新部门时才有意义。
这很清楚,但是为什么要删除关系但不能删除任何一个对象?如果删除 Course
,我希望删除 Course
并删除课程
进行主题,以便删除的 Course
出现故障不会出现在主题
的课程
设置的 NSSet
中
我想提供一种删除实体中所有对象的方法。当我通过分别获取和删除每个课程
进行尝试时,正确删除了个课程
并将其从<$ c $中删除c>在主题
上的个课程
的NSSet 。
由于我不知道会有多少个课程
,并且我想确保在每种情况下都具有较高的性能,因此我认为我将使用批量删除来删除所有课程
。问题是,在利用 NSBatchDeleteRequest
删除所有主题
时,可以正常工作,删除所有课程
(由于 Cascade
规则),试图使用此方法删除所有课程
方法似乎将所有对象保留在原处。
我使用了 NSBatchDeleteRequest
删除了所有课程
,但是当我查询 MOC
来查看主题
和课程
仍然存在,课程
仍然返回,并且主题
仍然拥有它们
相反,当我分别获取并删除每个 Course
时,随后的获取均会正确显示所有课程
的空数组,并且主题
上的'课程'关系似乎已被正确修改。
是的,我在执行请求后保存了上下文。我想可能不会通知上下文商店的工作,但是再次删除所有主题
效果很好。
在描述 NSBatchDeleteRequest
的WWDC 2015会话,解释为更改未反映在上下文中 。因此,您看到的是正常现象。批处理更新直接在永久性存储文件上运行,而不是通过托管对象上下文进行操作,因此上下文不了解它们。通过获取然后删除来删除对象时,您正在浏览上下文,因此它知道您正在进行的更改(实际上,它正在为您执行这些更改)。
如果使用 NSBatchDeleteResultTypeObjectIDs
,则可以使用 mergeChangesFromRemoteContextSave:intoContexts:$将批量删除的结果合并回上下文中c $ c>更新您的上下文。如果您没有从上下文中加载任何其他托管对象,则可能还可以使用
reset
。
I have seen many questions regarding batch deletion in Core Data, but none seem to address my issue.
I am creating an iOS 9 / Swift app using Core Data. At WWDC this year, I attended the Core Data session and saw that I could use NSBatchDeleteRequest
to delete large numbers of objects directly from the persistent store. This works for me for some objects but not others, and I think it has something to do with my relationships.
I have an object graph consisting of Subject
and Course
, where there is a one-to-many relationship. Subjects may own as many courses as they wish.
There is a 'courses' relationship on Subject
with a delete rule of Cascade
, as I want all courses associated with a subject
to be deleted when a subject
is deleted.
The inverse is 'subject' on Course
, with a delete rule of Nullify
. Here, I am a bit confused as to Apple's description of Nullify
:
Remove the relationship between the objects but do not delete either object. This only makes sense if the department relationship for an employee is optional, or if you ensure that you set a new department for each of the employees before the next save operation.
That makes it pretty clear, but why would the relationships be deleted but not either object? If I delete a Course
, I would like the Course
to be deleted and the relationship from the subject
to the course
to be deleted so that a fault to the deleted Course
will not appear in the NSSet
on Subject
's courses
Set.
I want to provide a way for all objects in an entity to be deleted. When I try this by individually fetching and deleting each course
, courses
are properly deleted and removed from the NSSet
of courses
on a Subject
.
Since I have no idea how many courses
will be present and I want to ensure high performance in every situation, I figured I would use batch deletion to delete all courses
. The problem is that while utilizing NSBatchDeleteRequest
to delete all Subjects
works fine, deleting all courses
along the way (because of the Cascade
rule), trying to delete all Courses
using this method appears to leave all objects in place.
I used NSBatchDeleteRequest
to delete all Courses
, but then when I query the MOC
to see what Subjects
and Courses
still exist, both Courses
are still returned and the Subject
owning them still has references to them.
In contrast, when I fetch and delete each Course
individually, my subsequent fetch properly displays an empty array for all Courses
and the 'courses' relationship on the Subject
appears to have been properly modified.
Yes, I am saving the context after executing the request. I suppose the context may not be notified of what the store does, but then again deleting all subjects
worked great. What is going on here?
At the WWDC 2015 session which describes NSBatchDeleteRequest
it was explained that "Changes are not reflected in the context". So what you're seeing is normal. Batch updates work directly on the persistent store file instead of going through the managed object context, so the context doesn't know about them. When you delete the objects by fetching and then deleting, you're working through the context, so it knows about the changes you're making (in fact it's performing those changes for you).
If you use NSBatchDeleteResultTypeObjectIDs
, you can merge the results of the batch delete back into your context using mergeChangesFromRemoteContextSave:intoContexts:
to update your contexts. You could probably also use reset
, if you don't have any other managed objects loaded from the context.
这篇关于核心数据NSBatchDeleteRequest似乎将对象留在上下文中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!