我与Realm合作已有一年多了,所以我对整个迁移流程并不陌生,但这让我ing了几天:
在将数据迁移到新的架构版本期间,我需要创建一些对象并将其插入数据库,然后再将它们连接到另一种对象。
首先,我创建了动态对象的映射,以便以后可以将它们连接到第二种类型:
val generatedStoreVisitTypes = mutableMapOf<String, DynamicRealmObject>()
然后我创建并使用dynamicObjects
fun migrateToVersion19(realm: DynamicRealm) {
// an extension method I created which adds the field if it doesn’t exist already, impl at the bottom
realm.schema.getOrCreate<RealmMetadata>()
// an extension method I created which adds the field if it doesn’t exist already, impl at the bottom
.safeAddRealmListField(RealmMetadata::storeVisitTypes, realm.schema)
.transform { metadata ->
// I use the string name of the property here and not reflection since this field is deleted during this migration
val currentStoreTaskList = metadata.getList("storeTasks")
currentStoreTaskList.forEach { storeTasks ->
// create an instance here and initialise it
val visitTypeTasks = realm.createObject(MetaVisitTypeTasks::class.java.simpleName)
visitTypeTasks[MetaVisitTypeTasks::visitTypeId.name] = "1"
val visitTasks = visitTypeTasks.getList(MetaVisitTypeTasks::visitTasks.name)
storeTasks.getList("storeTasks").forEach {
visitTasks.add(it)
}
// save the object to the map
generatedStoreVisitTypes[storeUid] = visitTypeTasks
}
}
.safeRemoveField("storeTasks")
realm.schema.getOrCreate<RealmStore>()
.safeAddRealmListField(RealmStore::visitTypes, realm.schema)
.transform {
val storeUid = it.getString(RealmStore::storeUid.name)
// crash here on the “add” method
it.getList(RealmStore::visitTypes.name).add(generatedStoreVisitTypes[storeUid])
}
}
}
private inline fun <reified T> RealmSchema.getOrCreate(): RealmObjectSchema {
return get(T::class.java.simpleName) ?: create(T::class.java.simpleName)
}
private inline fun <reified TClass : RealmObject, reified TListItem : RealmObject, reified TList : RealmList<TListItem>> RealmObjectSchema.safeAddRealmListField(addedField: KMutableProperty1<TClass, TList>, schema: RealmSchema): RealmObjectSchema {
val fieldName = addedField.name
val listItemObjectSchema = schema.get(TListItem::class.java.simpleName)
if (!hasField(fieldName)) {
return addRealmListField(fieldName, listItemObjectSchema)
}
return this
}
在第二个“转换”方法中调用“添加”方法有时会导致-
“ java.lang.IllegalStateException:对象不再有效,无法对其进行操作。它被另一个线程删除了吗?”
我对此错误很熟悉,通常知道如何处理该错误,但是在这种情况下我无法重新创建或理解这种情况。 既然我们在谈论迁移,那么不应有另一个线程在同一架构上运行-执行是同步的,不是吗? 另外,我们所说的是刚刚创建的对象。没有其他引用或使用上下文。
我不知道如何删除该对象。是什么原因导致这种错误?