在应用程序运行时替换 Core Data sqlite 文件,数据不更新

Posted

技术标签:

【中文标题】在应用程序运行时替换 Core Data sqlite 文件,数据不更新【英文标题】:Replacing Core Data sqlite file while app is running, data does not update 【发布时间】:2010-07-30 19:13:38 【问题描述】:

我正在为我的应用程序开发一个备份/恢复系统,用户可以在其中下载核心数据存储(sqlite 文件)的备份版本,并用下载的文件替换当前使用的数据存储。但是,一旦用户下载了文件并替换了当前数据存储,则似乎没有任何数据已更新。但是当应用程序退出并重新启动时,恢复的数据是可用的。如何强制我的应用重新加载核心数据存储的文件?

我试图从我的 UIViewController 访问应用程序委托,它会恢复数据,就像这样,重建核心数据堆栈并在导航堆栈中的所有视图控制器中传播它:

MyAppDelegate *app = [[UIApplication sharedApplication] delegate];
app.managedObjectContext = nil;
app.persistentStoreCoordinator = nil;
app.managedObjectModel = nil;
managedObjectContext = [app managedObjectContext];

NSArray *controllers = [self.navigationController viewControllers];
UIViewController *c;
for (int i = 0; i < [controllers count]; i++) 
    c = [controllers objectAtIndex:i];
    [c setManagedObjectContext:managedObjectContext];

但这不起作用,当我返回根视图控制器时它只会引发以下错误:'The NSManagedObject with ID:0x5d79060 &lt;x-coredata://D8E73D64-C9BA-4CFA-9213-F8BD61749155/MyObject/p2&gt; has been invalidated.'

有人知道如何强制应用重新加载数据并开始使用新的数据存储文件吗?

【问题讨论】:

【参考方案1】:

我认为让您感到困惑的是,即使您可以将所有托管对象上下文、存储协调器等设置为 nil,您仍然必须完全重新创建每个基于这些对象的正在使用的托管对象。

最好的办法是做你现在正在做的事情,但也要找到一种方法来销毁你使用过的每个 Core Data 对象。也许您可以将各种视图控制器弹出到根目录并从头开始重新加载该控制器,以便它使用您的新核心数据堆栈?你会失去一定程度的用户友好性(因为他们必须使用你加载的新数据重建视图控制器堆栈),但你会确定你已经销毁了你需要的一切。

【讨论】:

感谢您的回答。这很好用。你知道在这种情况下如何处理版本控制吗?我尝试用旧版本替换 sqlite 文件,它给了我一个“找不到源存储模型”的错误。 您需要明确地对模型文件进行版本控制。 Xcode 有执行此操作的工具 - 寻找将模型版本添加到现有 xcdatamodel 的选项。

以上是关于在应用程序运行时替换 Core Data sqlite 文件,数据不更新的主要内容,如果未能解决你的问题,请参考以下文章

在应用程序运行时启用/禁用 Core Data 的 iCloud 同步

在 Core Data 中替换多对多关系中的实体

当应用程序后台运行时,Core Data 无法通过区域监控保存上下文

Core-Data:想要将新的 web xml 内容持久保存到我的数据存储中,而不是替换现有的

在运行时动态创建 Core Data 实体

使用 Kiwi、Core Data 和 Magical Record 进行单元测试