【问题标题】:NSManagedObject's managedObjectContext property is nilNSManagedObject 的 managedObjectContext 属性为 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 仍然有正确的值。

标签: iphone core-data nsmanagedobjectcontext


【解决方案1】:

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

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

在任何一种情况下,上下文都没有强引用,超出范围,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,但我所有的数据都被保留了。我找不到任何说明它具有自动保存机制的文档,但根据我的经验,它确实可以做到这一点。既然这样做了,我就不能只丢弃数据,因为它已经为我放入了持久存储中。
猜你喜欢
  • 2011-03-26
  • 2011-07-25
  • 2016-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-09
相关资源
最近更新 更多