新领域迁移在新应用安装时被调用
New Realm migration gets called on new app installs
我有一个使用 Realm
的应用程序,它目前有两个不同的迁移,我正在处理第三个迁移,但由于某种原因,这个新迁移有一个奇怪的行为。我理解迁移的方式是,新迁移只会 运行 如果以前的模式版本已经存在,否则它们将被忽略,并且将根据模型的结构创建模式。
这是我看到的。
场景 1:工作正常。
如果之前安装了该应用程序,一切正常,新的迁移 3 运行s 并且它完成了它应该做的所有事情,数据成功转换并且一切正常。
情形 2:错误。
如果应用是第一次安装,用户一启动就开始添加数据,下次启动时(第二次调用AppDelegate)应用会崩溃。我放了一个打印语句,它看起来像应用程序第二次启动时的迁移 3 运行s 但不是在第一次启动时。
场景 3:破解后工作正常。
如果应用程序是第一次安装,但这次是用户
不会立即输入任何数据,而是 he/she 终止应用程序,然后再次重新启动应用程序,一切正常,没有错误,可以毫无问题地输入数据。
换句话说,看起来迁移 3 尝试 运行 应用程序第二次启动时发生错误,因为数据库已经具有第一次 运行 的正确模式结构].
错误场景 2:
libc++abi.dylib: terminating with uncaught exception of type 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 运行s。
我会先声明这是作为答案发布的,因为它试图验证问题中的代码在 OP 环境之外是否正常运行。
我已经获取了代码并在整个过程中添加了打印语句,因此可以在控制台中轻松地遵循代码流。
我们从删除所有文件开始,以便模拟应用程序的新安装。您的评论说您输入了数据,但这不是全新安装,因为用户还没有任何数据。
这是添加了一些打印语句的重复代码。对我来说,这是一个 macOS 应用程序,但 iOS 应用程序的行为相同。
迁移函数位于AppDelegate中,这样调用
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
self.doMigrate()
然后是函数
func doMigrate() {
print("starting schema version: \(Realm.Configuration.defaultConfiguration.schemaVersion)")
/// Migration 1:
Realm.Configuration.defaultConfiguration = Realm.Configuration(
schemaVersion: 1,
migrationBlock: { migration, oldSchemaVersion in
print("migration 1")
if (oldSchemaVersion < 1) {
print(" old schema < 1, performaing migration")
// configuration for schema 1
}
})
print("schema is now: \(Realm.Configuration.defaultConfiguration.schemaVersion)")
/// Migration 2:
Realm.Configuration.defaultConfiguration = Realm.Configuration(
schemaVersion: 2,
migrationBlock: { migration, oldSchemaVersion in
print("migration 2")
if (oldSchemaVersion < 2) {
print(" old schema < 2, performaing migration")
// configuration for schema 2
}
})
print("schema is now: \(Realm.Configuration.defaultConfiguration.schemaVersion)")
/// Migration 3:
Realm.Configuration.defaultConfiguration = Realm.Configuration(
schemaVersion: 3,
migrationBlock: { migration, oldSchemaVersion in
print("migration 3")
if (oldSchemaVersion < 3) {
print(" old schema < 3, performaing migration")
// configuration for schema 3
}
})
print("schema is now: \(Realm.Configuration.defaultConfiguration.schemaVersion)")
}
首先 运行,这是输出,注意没有发生迁移
starting schema version: 0
schema is now: 1
schema is now: 2
schema is now: 3
当代码是运行第二次时,输出是相同的
starting schema version: 0
schema is now: 1
schema is now: 2
schema is now: 3
即使我添加或更改模型、添加或更改数据,输出仍然保持不变 - 除了它确实崩溃,因为如果对象 属性 被删除,它需要迁移。
所以答案是:如果您没有看到相同的行为,则表明您的环境中有其他因素影响了 code/realm 结构。无论是 运行 一次还是 3 次,它的工作方式都是一样的。
我有一个使用 Realm
的应用程序,它目前有两个不同的迁移,我正在处理第三个迁移,但由于某种原因,这个新迁移有一个奇怪的行为。我理解迁移的方式是,新迁移只会 运行 如果以前的模式版本已经存在,否则它们将被忽略,并且将根据模型的结构创建模式。
这是我看到的。
场景 1:工作正常。
如果之前安装了该应用程序,一切正常,新的迁移 3 运行s 并且它完成了它应该做的所有事情,数据成功转换并且一切正常。
情形 2:错误。
如果应用是第一次安装,用户一启动就开始添加数据,下次启动时(第二次调用AppDelegate)应用会崩溃。我放了一个打印语句,它看起来像应用程序第二次启动时的迁移 3 运行s 但不是在第一次启动时。
场景 3:破解后工作正常。
如果应用程序是第一次安装,但这次是用户 不会立即输入任何数据,而是 he/she 终止应用程序,然后再次重新启动应用程序,一切正常,没有错误,可以毫无问题地输入数据。
换句话说,看起来迁移 3 尝试 运行 应用程序第二次启动时发生错误,因为数据库已经具有第一次 运行 的正确模式结构].
错误场景 2:
libc++abi.dylib: terminating with uncaught exception of type 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 运行s。
我会先声明这是作为答案发布的,因为它试图验证问题中的代码在 OP 环境之外是否正常运行。
我已经获取了代码并在整个过程中添加了打印语句,因此可以在控制台中轻松地遵循代码流。
我们从删除所有文件开始,以便模拟应用程序的新安装。您的评论说您输入了数据,但这不是全新安装,因为用户还没有任何数据。
这是添加了一些打印语句的重复代码。对我来说,这是一个 macOS 应用程序,但 iOS 应用程序的行为相同。
迁移函数位于AppDelegate中,这样调用
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
self.doMigrate()
然后是函数
func doMigrate() {
print("starting schema version: \(Realm.Configuration.defaultConfiguration.schemaVersion)")
/// Migration 1:
Realm.Configuration.defaultConfiguration = Realm.Configuration(
schemaVersion: 1,
migrationBlock: { migration, oldSchemaVersion in
print("migration 1")
if (oldSchemaVersion < 1) {
print(" old schema < 1, performaing migration")
// configuration for schema 1
}
})
print("schema is now: \(Realm.Configuration.defaultConfiguration.schemaVersion)")
/// Migration 2:
Realm.Configuration.defaultConfiguration = Realm.Configuration(
schemaVersion: 2,
migrationBlock: { migration, oldSchemaVersion in
print("migration 2")
if (oldSchemaVersion < 2) {
print(" old schema < 2, performaing migration")
// configuration for schema 2
}
})
print("schema is now: \(Realm.Configuration.defaultConfiguration.schemaVersion)")
/// Migration 3:
Realm.Configuration.defaultConfiguration = Realm.Configuration(
schemaVersion: 3,
migrationBlock: { migration, oldSchemaVersion in
print("migration 3")
if (oldSchemaVersion < 3) {
print(" old schema < 3, performaing migration")
// configuration for schema 3
}
})
print("schema is now: \(Realm.Configuration.defaultConfiguration.schemaVersion)")
}
首先 运行,这是输出,注意没有发生迁移
starting schema version: 0
schema is now: 1
schema is now: 2
schema is now: 3
当代码是运行第二次时,输出是相同的
starting schema version: 0
schema is now: 1
schema is now: 2
schema is now: 3
即使我添加或更改模型、添加或更改数据,输出仍然保持不变 - 除了它确实崩溃,因为如果对象 属性 被删除,它需要迁移。
所以答案是:如果您没有看到相同的行为,则表明您的环境中有其他因素影响了 code/realm 结构。无论是 运行 一次还是 3 次,它的工作方式都是一样的。