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 语句之后(即使在 viewDidLoad
、self.someManagedObject.managedObjectContext
内也是 nil。我可以看到为什么局部变量不再可用(它只是超出了范围),但托管对象的属性应该还是定的吧?
我知道我可以创建一个属性来存储托管对象上下文,但我宁愿让它以这种方式工作。
【问题讨论】:
是someObject
和someManagedObject
一样吗?
哎呀,是的。我先放了someObject
,但后来想澄清它是一个NSManagedObject。
你检查过self.someManagedObject
不是零?假设 insertNewObject...
失败或您的属性是特殊的,这将解释您所看到的。
是的,self.managedObject
仍然有正确的值。
【参考方案1】:
我最近又遇到了同样的问题,尽管情况不同。我需要一个临时托管对象上下文,与主对象上下文完全分开,但我再次遇到了它在超出范围后消失的问题。这一次我决定进一步调查,我最终意识到managedObjectContext
不是NSManagedObject
的一个属性,而是一个方法。这意味着两件事之一:
-
如果它使用底层实现中的属性,则该属性will not hold a strong reference 到上下文
如果托管对象上下文以其他方式派生,它也不会持有对该上下文的强引用。
在任何一种情况下,上下文都没有强引用,超出范围,NSManagedObject
s 有一个nil
managedObjectContext
。
解决方案是通过为其创建一个强大的属性来简单地保留上下文。
【讨论】:
你知道为什么会这样吗? (为此我有一个单独的 SO question...) 描述的链接不再起作用。更多数据可以在这里找到。developer.apple.com/documentation/coredata/nsmanagedobject/…managedObjectContext
在NSManagedObject
中被定义为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 处理的“原始”对象