当内联初始化上下文时,为什么 NSManagedObject 没有插入到子 NSManagedObjectContext 中?
Why does NSManagedObject not get inserted into a child NSManagedObjectContext when the context is initialised inline?
我在我的 iOS 应用程序中使用子 NSManagedObjectContext
作为暂存器。我正在使用 NSManagedObjectContext
的扩展来创建子上下文,如下所示:
extension NSManagedObjectContext {
func childContext(concurrencyType: NSManagedObjectContextConcurrencyType = .mainQueueConcurrencyType) -> NSManagedObjectContext {
let childContext = NSManagedObjectContext(concurrencyType: concurrencyType)
childContext.parent = self
return childContext
}
}
在将新的 NSManagedObject
插入新的子上下文(从 NSPersistentContainer
的 viewContext
中创建时,我的应用程序的一部分反复出现以下消息错误):
CoreData: error: Mutating a managed object after it has been removed from its context
这很奇怪,因为应用程序的其他部分(也使用了子上下文)运行良好。最终,我将原因缩小到将新的 NSManagedObject
(实体名称 "Book")插入新的子上下文的方式存在细微差别。以下按预期工作:
let childContext = container.viewContext.childContext()
let object1 = NSEntityDescription.insertNewObject(forEntityName: "Book", into: childContext)
print(object1.managedObjectContext == nil)
// prints "false"
但是,如果我创建内联子上下文(即未分配给变量,托管对象未插入到上下文):
let object2 = NSEntityDescription.insertNewObject(forEntityName: "Book", into: container.viewContext.childContext())
print(object2.managedObjectContext == nil)
// prints "true"
这对我来说似乎很奇怪,无法弄清楚。一切都在主线程上 运行 。我还创建了一个重现此行为的 Swift playground。
托管对象有一个 managedObjectContext
属性,但它是一个弱引用。这意味着拥有托管对象不会阻止上下文被释放。如果上下文被释放,managedObjectContext
属性 会自动设置为 nil。
在您的第一个代码片段中,childContext
作为局部变量存在于创建托管对象的代码中。插入新对象后,它仍然存在于本地范围内,因此 managedObjectContext
属性 仍然指向上下文。 childContext
变量保持强引用,所以对象仍然存在。
在第二个片段中,子上下文仅作为 insertNewObject
的参数存在。一旦该方法 returns,上下文就会超出范围。由于没有对上下文的强引用,它被释放,并且 object2.managedObjectContext
自动设置为 nil。
我在我的 iOS 应用程序中使用子 NSManagedObjectContext
作为暂存器。我正在使用 NSManagedObjectContext
的扩展来创建子上下文,如下所示:
extension NSManagedObjectContext {
func childContext(concurrencyType: NSManagedObjectContextConcurrencyType = .mainQueueConcurrencyType) -> NSManagedObjectContext {
let childContext = NSManagedObjectContext(concurrencyType: concurrencyType)
childContext.parent = self
return childContext
}
}
在将新的 NSManagedObject
插入新的子上下文(从 NSPersistentContainer
的 viewContext
中创建时,我的应用程序的一部分反复出现以下消息错误):
CoreData: error: Mutating a managed object after it has been removed from its context
这很奇怪,因为应用程序的其他部分(也使用了子上下文)运行良好。最终,我将原因缩小到将新的 NSManagedObject
(实体名称 "Book")插入新的子上下文的方式存在细微差别。以下按预期工作:
let childContext = container.viewContext.childContext()
let object1 = NSEntityDescription.insertNewObject(forEntityName: "Book", into: childContext)
print(object1.managedObjectContext == nil)
// prints "false"
但是,如果我创建内联子上下文(即未分配给变量,托管对象未插入到上下文):
let object2 = NSEntityDescription.insertNewObject(forEntityName: "Book", into: container.viewContext.childContext())
print(object2.managedObjectContext == nil)
// prints "true"
这对我来说似乎很奇怪,无法弄清楚。一切都在主线程上 运行 。我还创建了一个重现此行为的 Swift playground。
托管对象有一个 managedObjectContext
属性,但它是一个弱引用。这意味着拥有托管对象不会阻止上下文被释放。如果上下文被释放,managedObjectContext
属性 会自动设置为 nil。
在您的第一个代码片段中,childContext
作为局部变量存在于创建托管对象的代码中。插入新对象后,它仍然存在于本地范围内,因此 managedObjectContext
属性 仍然指向上下文。 childContext
变量保持强引用,所以对象仍然存在。
在第二个片段中,子上下文仅作为 insertNewObject
的参数存在。一旦该方法 returns,上下文就会超出范围。由于没有对上下文的强引用,它被释放,并且 object2.managedObjectContext
自动设置为 nil。