我在iPhone应用程序上使用核心数据。我有多个persisntent商店,我正在从一个商店切换到另一个,所以当时只有一个商店可以活跃。我有一个托管对象上下文,不同的持久存储在数据格式(sqlite)中是相似的,并共享相同的托管对象模型。
我将数据从相应的XML文件导入每个持久性存储。对于第一次导入,一切正常,但在我删除导入的数据(持久存储和物理文件)然后重新导入后,核心数据给我一个错误:
*** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'The NSManagedObject with ID:0x3c14e00 <x-coredata://6D14F11E-2EA7-4141-9BE8-53747DE6FCC6/Book/p2> has been invalidated.'
此错误来自NSManagedObjectContext的save :.在重新导入之前,我正在从持久性存储协调器中删除持久性存储并删除物理文件,因此一切都应该像第一次重新导入一样。 Alos,托管对象上下文中的对象被删除,上下文被发送reset:消息(我不知道这是否真的需要)。
有人可以帮助我吗?如何切换持久性存储?
我基本上使用与此处辅导相同的逻辑:http://blog.sallarp.com/iphone-core-data-uitableview-drill-down/
提前致谢。
感谢您的回答。
对我目标模糊的道歉。我正在开发一个圣经阅读器应用程序,它将从XML导入到核心数据SQL。目前只能使用一种翻译。目前我对每个翻译只有不同的MOC和PS,因为模型是相同的。但是,我确实相信,如果你说堆栈应该作为一个整体创建。翻译彼此之间没有连接,因此没有使用相同堆栈的实际原因。唯一可能使此复杂化的是注释/书签/等将引用活动翻译。但是,引用将是文本的,因此不再需要共享堆栈。
感谢您的投入。
答案 0 :(得分:2)
我同意路易斯的观点,你所做的是一个危险的设计,你应该重建整个堆栈而不是像这样换掉商店。重建完整堆栈并不是一个巨大的开销。
此外,如果您使用完全不同的模型和完全不同的数据对象,则无需删除它们,您可以将所有模型一起添加到一个持久存储中,并根据您创建的实体,Core Data将执行的操作是对的。
如果您使用相同的实体构建多个模型,那么问题是为什么?你不会从中获得任何性能上的好处。
在您描述的情况下,我会将所有存储放入单个持久性存储协调器,然后指示上下文存储以使用-assignObject:toPersistentStore:
保存实体。这将消除构建和拆除多个核心数据堆栈的需要。
新堆栈是整个堆栈。 PSC,MOM和MOC。你正在从核心数据堆栈中拉出地毯,然后期望它只是弄清楚你在做什么。
你的最终目标是什么?
嗯,那么只创建PS和MOC以及使用现有的PSC和MOM会是什么样的可接受场景?如果我猜到,我会说每次我对现有堆栈进行修改时,都应该重新创建,如果使用了多个商店,则应该在构建时引入它们。
NSManagedObjectModel
,NSPersistentStoreCoordinator
和NSPersistentStore
紧密相连,因此目前尚不清楚您的目标是什么。如果你用你想要实现的目标更新你的问题,它将使答案变得更加模糊。
当您处理多个线程和一些非常罕见的边缘情况时,通常会使用多个NSManagedObjectContext
实例。当您有数据需要因某种原因而被孤立时(部分只读等),通常会使用多个NSPersistentStore
实例。这些是正常的用例。
我的问题仍然存在,你想要完成什么?
我正在开发一个圣经阅读器应用程序,它将从XML导入到核心数据SQL。目前只能使用一种翻译。
好的,每次翻译都不需要单独的文件,这是一种浪费。由于每个翻译都由代码(例如ASM)和名称,版权等标识,因此您可以在设计中创建一个名为“翻译”的顶级实体,其余数据从那里分支。没有多重背景,没有切换的东西,它只是有效。
您需要多个文件的唯一时间是,如果您使用的是多文档设计,而不是您在iPhone上执行的操作。
答案 1 :(得分:1)
几乎可以肯定的是,您使用的NSManagedObjectContext仍然具有对分离的持久性存储所支持的对象的内部引用。处理此问题的最简单方法是不重用上下文。
我不清楚为什么要重用相同的持久性存储协调器或托管对象上下文。如果这些事实上是概念上独立的事物(这样你只能使用一个),为什么你要重用一个可能存在陈旧状态的现有堆栈(这就是造成你的问题的原因)。
创建和销毁NSManagedObjectContexts非常轻量级。创建一个全新的PSC有点重,但在你正在做的事情(移动文件和导入XML)的规模上,它可能也不可测量。