为什么在内联初始化上下文时,NSManagedObject不会插入到子NSManagedObjectContext中?

时间:2018-02-25 23:01:08

标签: ios swift core-data nsmanagedobject nsmanagedobjectcontext

我在iOS应用中使用子NSManagedObjectContext作为暂存器。我正在使用NSManagedObjectContext的扩展来创建子上下文,如下所示:

extension NSManagedObjectContext {
    func childContext(concurrencyType: NSManagedObjectContextConcurrencyType = .mainQueueConcurrencyType) -> NSManagedObjectContext {
        let childContext = NSManagedObjectContext(concurrencyType: concurrencyType)
        childContext.parent = self
        return childContext
    }
}

在将新NSManagedObject插入到新的子上下文(从viewContext的{​​{1}}创建)时,我的应用的一部分出现了以下消息,但我遇到了重复错误:

  

CoreData:错误:在托管对象从其上下文中删除后对托管对象进行变更

这很奇怪,因为应用程序的其他部分 - 也使用了子环境 - 运行良好。最后,我将原因缩小到我将新NSPersistentContainer(实体名称" Book")插入新子上下文的方式的一小部分差异。以下按预期工作:

NSManagedObject

但是,如果我内联创建子上下文(即未分配给变量,则托管对象插入上下文中):

let childContext = container.viewContext.childContext()
let object1 = NSEntityDescription.insertNewObject(forEntityName: "Book", into: childContext)
print(object1.managedObjectContext == nil)
// prints "false"

这对我来说似乎很奇怪,无法弄明白。一切都在主线程上运行。我还创建了Swift playground来重现这种行为。

1 个答案:

答案 0 :(得分:2)

托管对象具有managedObjectContext属性,但它是一个弱引用。这意味着拥有托管对象不会阻止上下文被释放。如果取消分配上下文,则managedObjectContext属性将自动设置为nil。

在您的第一个代码段中,childContext作为创建托管对象的代码中的局部变量而存在。插入新对象后,它仍然存在于本地范围内,因此managedObjectContext属性仍指向上下文。 childContext变量保留强引用,因此对象仍然存在。

在第二个片段中,子上下文仅作为insertNewObject的参数存在。该方法返回后,上下文超出范围。由于没有对上下文的强引用,因此将其取消分配,object2.managedObjectContext自动设置为nil。