Realm 从多个版本升级域迁移崩溃

Realm 从多个版本升级域迁移崩溃,realm,swift4,Realm,Swift4,注: 这仅在用户从2升级到4时发生,但如果用户从2、3升级到4,则不会发生此错误。update2to3不会在oldObject上创建地址,并且不可能这样做。直接从版本2升级到版本4时,update2to3和update3to4都会获得版本2 oldObjects和版本4 newObjects 对于问题中显示的迁移,最简单的修复方法是完全删除迁移函数,因为它们只是重复添加新属性时Realm自动执行的操作。我注意到了这一点。oldObject还没有地址字段。我们无法删除迁移,因为添加新属性时域崩溃。

注: 这仅在用户从2升级到4时发生,但如果用户从2、3升级到4,则不会发生此错误。

update2to3不会在oldObject上创建地址,并且不可能这样做。直接从版本2升级到版本4时,update2to3和update3to4都会获得版本2 oldObjects和版本4 newObjects


对于问题中显示的迁移,最简单的修复方法是完全删除迁移函数,因为它们只是重复添加新属性时Realm自动执行的操作。

我注意到了这一点。oldObject还没有地址字段。我们无法删除迁移,因为添加新属性时域崩溃。这就是为什么我们在添加地址字段时创建迁移,因为Realm抱怨该属性在以前的版本中不存在。在添加属性时,您必须碰撞架构版本,但迁移函数不需要做任何事情。您的意思是我只需要增加架构版本,这就是诀窍吗?我很困惑,因为我发现的大多数线程都告诉我增加模式版本并创建迁移块。无论如何,我们刚刚删除了update3to4中的更改,但update2to3仍然存在,因为该应用程序已部署用于生产使用。顺便说一句,我接受了这个答案,因为它解释了发生这种情况的原因。是的,除非您特别想将新属性初始化为该类型的空值以外的其他值,否则添加新属性时只需增加架构版本。
func runMigration(migration: Migration, olderVersion: UInt64, newVersion: UInt64) {
    // upgrade from version 2 to 3
        if olderVersion <= 2 && newVersion >= 3 {
            update2to3(migration)
        }

    // upgrade from version 3 to 4
        if olderVersion <= 3 && newVersion >= 4 {
            update3to4(migration)
        }
}

private func update2to3(_ migration: Migration) {
    migration.enumerateObjects(ofType: Student.className(), {oldObject, newObject in
            newObject?[“address”] = “”
        })
}

private func update3to4(_ migration: Migration) {
    migration.enumerateObjects(ofType: Student.className(), {oldObject, newObject in
            newObject?[“address”] = oldObject?["address"] ?? nil
        })
}
Terminating app due to uncaught exception 'RLMException', reason: 'Invalid property name 'address' for class 'Student'.'