【发布时间】:2020-01-19 15:29:46
【问题描述】:
我有一个使用 Realm 的应用程序,它目前有两个不同的迁移,我正在处理第三个迁移,但由于某种原因,这个新迁移的行为很奇怪。我理解迁移的方式是,只有在以前的架构版本已经存在时,新的迁移才会运行,否则它们将被忽略,架构将基于模型的结构创建。
这就是我所看到的。
场景 1:工作正常。
如果之前安装了该应用程序,一切正常,新的迁移 3 运行,它完成了它应该做的一切,数据成功转换,一切正常。
场景 2:错误。
如果是第一次安装应用,用户一启动就开始添加数据,下一次启动应用就会崩溃(第二次调用 AppDelegate)。我放了一条打印语句,看起来迁移 3 在应用程序第二次启动时运行,但不是在第一次启动时运行。
场景 3:破解后工作正常。
如果应用是第一次安装,但这次是用户 不会立即输入任何数据,而是将应用程序杀死,然后再次重新启动应用程序,一切正常,没有错误,可以毫无问题地输入数据。
换句话说,migration 3 似乎在应用程序第二次启动时尝试运行,此时发生错误,因为数据库在第一次运行时已经具有正确的架构结构。
错误场景 2:
libc++abi.dylib:以 NSException 类型的未捕获异常终止
知道为什么迁移 3 会在新安装的第二次启动时运行吗?这似乎不是正常行为,为什么它会运行第二次而不是第一次启动。
有什么想法吗?
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
/// Migration 1:
Realm.Configuration.defaultConfiguration = Realm.Configuration(
schemaVersion: 1,
migrationBlock: { migration, oldSchemaVersion in
if (oldSchemaVersion < 1) {
// configuration for schema 1
}
})
/// Migration 2:
Realm.Configuration.defaultConfiguration = Realm.Configuration(
schemaVersion: 2,
migrationBlock: { migration, oldSchemaVersion in
if (oldSchemaVersion < 2) {
// configuration for schema 2
}
})
/// Migration 3:
Realm.Configuration.defaultConfiguration = Realm.Configuration(
schemaVersion: 3,
migrationBlock: { migration, oldSchemaVersion in
if (oldSchemaVersion < 3) {
// configuration for schema 3
}
})
}
}
仅供参考 - 我在每次迁移中都有打印,并且在第一次安装应用程序后的第二次应用程序启动时仅运行迁移 3。
【问题讨论】:
-
我相信你的意思是 migration block 运行,而不是模式。 Schema 描述了数据的结构并且不运行。当应用程序第一次运行时,没有这样的 schemaVersion,因此将根据它们所处的任何状态创建默认对象。但是,由于问题中提供的代码序列,在第一次运行时,架构版本最终会是 3。这是故意的吗?
-
@Jay - 是的,你是对的,我的意思是迁移,我已经纠正了我的问题。我的应用程序目前已通过第二次迁移发布。我现在添加了第三次迁移,以便能够将
Double转换为双精度列表List<Double>,因此我在第三次迁移中处理数据转换。我只希望为已经安装应用程序的用户而不是新用户运行第三次迁移,根据我上面显示的迁移代码,这个假设是否正确?谢谢 -
@Jay - 你介意为我澄清以下内容吗?根据我展示的迁移顺序,迁移 3 是否会为新用户运行?我的意图是为已有架构 1 或 2 的现有用户运行迁移 3,但不为新用户运行。
-
不,不会发生迁移,因为新用户以前不存在该领域。所有对象都将是新鲜的,无需迁移 - 请参阅我的第一条评论。但是,模式版本将设置为 3。您可以通过在闭包中添加一些打印语句来测试它。删除现有领域并运行它。
-
由于
oldSchemaVersion < 3,如果架构版本为 3,则无法运行迁移 3 中的实际迁移。这告诉我在您的问题中的代码之外还有其他事情发生,因为它可以运行的唯一方法是 oldSchemaVersion 为
标签: ios swift realm database-migration realm-migration