NSManagedObject 的 managedObjectContext 属性为 nil

Posted

技术标签:

【中文标题】NSManagedObject 的 managedObjectContext 属性为 nil【英文标题】:NSManagedObject's managedObjectContext property is nil 【发布时间】:2012-08-02 23:00:07 【问题描述】:

我正在尝试创建一个临时托管对象上下文,在用户输入信息的几个屏幕之后,我将该上下文与主上下文合并(以确保没有插入“不完整”的对象)。这就是我创建临时上下文以及在其中插入对象的方式:

if (!self.someManagedObject) 

    NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:@[[NSBundle mainBundle]]];
    NSPersistentStoreCoordinator *storeCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
    [storeCoordinator addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:nil];

    NSManagedObjectContext *managedObjectContext = [[NSManagedObjectContext alloc] init];
    [managedObjectContext setPersistentStoreCoordinator:storeCoordinator];

    self.someManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"SomeObject" inManagedObjectContext:managedObjectContext];
    NSLog(@"%@", self.someManagedObject.managedObjectContext);

这是viewDidLoad 的一部分。在控制台中,它显示托管对象上下文有一个值。

但是,在这个 if 语句之后(即使在 viewDidLoadself.someManagedObject.managedObjectContext 内也是 nil。我可以看到为什么局部变量不再可用(它只是超出了范围),但托管对象的属性应该还是定的吧?

我知道我可以创建一个属性来存储托管对象上下文,但我宁愿让它以这种方式工作。

【问题讨论】:

someObjectsomeManagedObject 一样吗? 哎呀,是的。我先放了someObject,但后来想澄清它是一个NSManagedObject。 你检查过self.someManagedObject 不是零?假设 insertNewObject... 失败或您的属性是特殊的,这将解释您所看到的。 是的,self.managedObject 仍然有正确的值。 【参考方案1】:

我最近又遇到了同样的问题,尽管情况不同。我需要一个临时托管对象上下文,与主对象上下文完全分开,但我再次遇到了它在超出范围后消失的问题。这一次我决定进一步调查,我最终意识到managedObjectContext不是NSManagedObject的一个属性,而是一个方法。这意味着两件事之一:

    如果它使用底层实现中的属性,则该属性will not hold a strong reference 到上下文 如果托管对象上下文以其他方式派生,它也不会持有对该上下文的强引用。

在任何一种情况下,上下文都没有强引用,超出范围,NSManagedObjects 有一个nil managedObjectContext

解决方案是通过为其创建一个强大的属性来简单地保留上下文。

【讨论】:

你知道为什么会这样吗? (为此我有一个单独的 SO question...) 描述的链接不再起作用。更多数据可以在这里找到。developer.apple.com/documentation/coredata/nsmanagedobject/… managedObjectContextNSManagedObject 中被定义为unowned(unsafe) open var managedObjectContext: NSManagedObjectContext? get ,因为该属性不会持有强引用。【参考方案2】:

我不明白您为什么需要第二个托管对象上下文。恕我直言,您正在将复杂性引入您的应用程序中,而这并不适用于任何特定目的。

将新对象插入主上下文。让用户输入他的数据。如果他中断,只需调用

[managedObjectContext rollback];

或者,如果用户完成并验证了所有数据,则调用

[managedObjectContext save:nil];

【讨论】:

这似乎也是一个很好的解决方案,但rollback 可以追溯到多远?到最后一次保存?我有点依赖自动保存,所以我必须手动调用save(这不是问题,但我必须知道)。 最后保存 - 它可能比这更复杂一些,但仅限于特殊情况。 - 另外,我不知道“自动保存”。明确地这样做当然更好。 我这样做有一个问题:我必须检查用户可以避免填写所有信息的所有可能方式。我不想检查用户是否做了“错误”的事情(如进程被中断),我希望能够在进程完成时保存。我所说的过程是指“浏览用户输入信息的屏幕”。我不想每次可能的中断都打电话给rollback 也可以。只需跟踪您要保存的数据,并在用户完成时保存它 - 当用户确定中断该过程时将其丢弃。但是,原则上这也是回滚的作用。第二个 MOC 在这里帮不了你。 问题在于自动保存。我有另一个使用 Core Data 的应用程序,我从来没有在那里打电话给save,但我所有的数据都被保留了。我找不到任何说明它具有自动保存机制的文档,但根据我的经验,它确实可以做到这一点。既然这样做了,我就不能只丢弃数据,因为它已经为我放入了持久存储中。

以上是关于NSManagedObject 的 managedObjectContext 属性为 nil的主要内容,如果未能解决你的问题,请参考以下文章

原因:'一个'NSManagedObject'类的NSManagedObject必须有一个有效的NSEntityDescription? [复制]

“NSManagedObject”类的 NSManagedObject 必须具有有效的 NSEntityDescription

NSManagedObject 故障/无法获得由 NSManagedObject 处理的“原始”对象

NSManagedObject - NSSet 被删除?

属性作为“当前 NSManagedObject”的视图控制器中的 NSManagedObject

如何根据现有的 NSManagedObject 值在 NSManagedObject 派生类中设置默认值?