我有两个实体,每个实体都在自己的UITableView部分显示。
我已启用编辑功能,允许用户通过向右滑动来删除行。这适用于第一个实体,但是当我尝试删除第二个实体中的对象时,我收到此错误:
An NSManagedObjectContext cannot delete objects in other contexts
我得到错误说的内容,但我看不出它在这里是如何适用的。我使用对上下文的保留引用来创建,获取和删除数据库中的所有对象,因此我确信只有一个上下文。我也没有使用多线程。知道会发生什么吗?
答案 0 :(得分:24)
您从同一实例获取NSManagedObject
的上下文是否与您用来删除NSManagedObject
的上下文相同?如果没有,您需要:
NSManagedObjectContext
的共享引用,以便从您创建或从中获取的相同上下文中删除该对象。如果您没有使用多个线程,那么您只需要在代码中调用[[NSManagedObjectContext alloc] init]
。或
如果您必须使用NSManagedObjectContext
的两个不同实例,请从第一个上下文中获取的objectID
中获取NSManagedObject
,以便稍后调用:
[context deleteObject:[context objectWithID:aObjectID]];
上下文之间NSManagedObjectID
是相同的,但NSManagedObject
本身不是。
答案 1 :(得分:0)
这个答案阐述了Riley Dutton关于错误信息具有误导性的评论中描述的案例。
将不 NSManagedObject的子类的对象传递给deleteObject:
时,将显示错误消息。 Riley只是通过明确地传入错误的对象来解决问题,但是我通过Core Data的变化来实现这一目标。
我的项目部署目标设置为7.0,即使在iOS 9.3上运行,此代码仍可正常运行:
NSArray *entries = @[self.colorList.colors, self.emotionList.emotions, self.shapeList.shapes];
for (id entry in entries) {
[[self managedObjectContext] deleteObject:entry];
}
当我将项目部署目标更新为9.3时,我开始收到错误消息。
以下是entry
:
Relationship 'colors' fault on managed object (0x7fd063420310) <MyColorList: 0x7fd063420310> (entity: MyColorList; id: 0xd000000000640006 <x-coredata://12556DEF-F77E-4EFF-AAE6-55E71A3F5420/MyColorList/p25> ; data: {
attachedThing = "0xd0000000000c0004 <x-coredata://12556DEF-F77E-4EFF-AAE6-55E71A3F5420/MyThing/p3>";
colors = "<relationship fault: 0x7fd063468f30 'colors'>";
})
Apple似乎更改了Core Data何时触发故障并实际从持久性存储协调器中提取数据的规则。
这个修改解决了这个问题:
NSArray *entries = @[self.colorList.colors, self.emotionList.emotions, self.shapeList.shapes];
for (id entry in entries) {
for (id e in entry) {
[[self managedObjectContext] deleteObject:e];
}
}
此时我不知道这是否是解决此问题的理想方法,或者是否有更规范的方法告诉Core Data触发故障并从磁盘读取数据。
答案 2 :(得分:0)
我用这个:
func delete(object: YourManagedObject) {
guard let context = object.managedObjectContext else { return }
if context == self.viewContext {
context.delete(object)
} else {
self.performBackgroundTask { context in
context.delete(object)
}
}
try? self.viewContext.save()
}
基本上,您要删除的对象很可能是由 NSPersistentContainer 的 viewContext 提供的。因此,尝试从私人背景环境中删除不会起作用。
答案 3 :(得分:0)
我不确定它是否能回答您的问题,但是当我尝试在Swift中删除CoreData对象时发生了类似的崩溃。我修复了它的objectId
func deleteNumber(phoneNumber: PhoneNumber) {
let objectToDelete = container.viewContext.object(with: phoneNumber.objectID)
container.viewContext.delete(objectToDelete)
//save context
if container.viewContext.hasChanges {
do {
try container.viewContext.save()
} catch {
print("An error occurred while saving: \(error)")
}
}
}
答案 4 :(得分:0)
在补充使用dominostars给出的答案时,使用SwiftUI时,只需像@Environment(\.managedObjectContext) var moc
一样声明对托管对象上下文的引用,然后将此引用传递给其他需要访问的视图。不要两次声明引用。
答案 5 :(得分:-2)
好吧,试试这个;这可以解决您的问题: -
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
//delete Entity
});
然后得到了同样的错误。
尝试删除主线程中的实体后,此问题已修复。