不兼容的 CoreData 存储是不是总是导致崩溃?

Posted

技术标签:

【中文标题】不兼容的 CoreData 存储是不是总是导致崩溃?【英文标题】:Does an incompatible CoreData store always cause a crash?不兼容的 CoreData 存储是否总是导致崩溃? 【发布时间】:2017-02-22 08:40:26 【问题描述】:

问题:

我们最近在我们的应用中引入了 CoreData,之前发布了一个带有不完整 CoreData 模型的版本。在发布的版本中,我们从未实现将数据写入 sqlite 数据库的代码,只实现了模型。

在我们的内部测试中,我们会将我们的设备恢复为之前发货的不完整型号,然后更新到较新的型号,并且无需执行迁移,也没有遇到不兼容的商店异常。

但是,在我们的 Beta 测试中,我们发现现有用户由于商店不兼容而遇到崩溃,而一些现有用户则没有。

问题:

不兼容的存储是否总是会导致崩溃,如果是这样,为什么我们在从旧版本更新到不同的 CoreData 模型时不会遇到崩溃?

我应该提到,当我们对最新的 CoreData 模型进行更改时,我们确实会抛出不兼容的存储错误,但是当我们恢复到我们的核心数据模型的非常原始版本时,我们不会看到抛出这个异常。

【问题讨论】:

当您对 coredata 进行任何更改时,如果您仍然使用旧版本,则必须删除旧版本并使用新版本,这样会导致您崩溃。 看看:raywenderlich.com/27657/… 如果您在安装前删除了您设备上的应用程序,那么它就没有 CoreData 架构冲突,因此不会崩溃。如果您的测试用户在使用具有不同 CoreData 架构的新版本应用程序之前没有从他们的设备上删除该应用程序,那么架构中的冲突将导致崩溃。 【参考方案1】:

回答您的问题,如果您的项目中调用了以下代码行

[__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                    configuration:nil
                                                              URL:storeURL
                                                          options:nil
                                                            error:&error])

当您使用 CoreData 设置项目时 Xcode 自动添加的代码是的,不兼容的存储总是会导致崩溃,除非您根据您的情况进行轻度迁移或重度迁移。

轻量级迁移非常简单直接,但您必须遵守一些规则。对于轻度迁移,您将上面的代码行更改为:

 [__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                        configuration:nil
                                                                  URL:storeURL
                                                              options:@NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES
                                                                error:&error])

您可以在developer.apple上查看更多关于轻量级迁移的信息

您还应该查看@raki 在 cmets 中发布的链接。

【讨论】:

谢谢,丹尼帕塔。回顾我们交付的不完整核心数据构建,我们有声明持久存储协调器的代码,但它从未被调用。这就是为什么我们只看到一些用户崩溃的原因,而不是全部?我们的行动计划是完全删除持久存储(如果它不兼容),然后创建一个新存储并从我们的服务器加载数据,因为迁移可能会很繁重。我们已经将本地数据与外部服务器同步,因此代码是即插即用的。对这种方法有什么想法? 不知道为什么一直不调用代码就崩溃了,说明根本没有设置核心数据,崩溃可能来自其他地方。关于重新创建持久存储,在我看来,如果您不使用核心数据关系(一对多、多对多),我会直接缓存在文件中,因为您将所有数据与你的服务器。核心数据的一个更好的替代方案是 Realm(检查一下),它的速度非常快,但是就像核心数据一样,您必须处理迁移,实际上我认为没有一种缓存方法不需要某种迁移。

以上是关于不兼容的 CoreData 存储是不是总是导致崩溃?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 CoreData 中保存位置

CoreData insertNewObjectForEntityForName 导致崩溃

我无法重现的用户可能会导致 CoreData 崩溃

CoreData iPad 应用程序崩溃

不总是导致程序崩溃的预期缓冲区溢出

由于 iOS 持久性商店问题和未从 Coredata 加载数据而导致应用程序崩溃