Realm (Swift) 迁移时如何正确获取 MutableSet 类型的字段数据?
问题原因
在Realm的迁移block中,你通过oldObject拿到的所有对象都不是你定义的Player、PositionClass等实际Model类的实例,而是MigrationObject类型的动态代理对象。你直接将集合强转为MutableSet<PositionClass>时,Swift类型检查会失败,所以始终返回nil,调试器看到的是底层存储的类型标识,和Swift层面的类型转换无关。
解决方法
你可以通过Foundation的NSSet桥接拿到旧的集合数据,再按业务需要排序后写入新的List字段即可,示例代码如下:
let schemaVersion: UInt64 = 22 let config = Realm.Configuration(schemaVersion: schemaVersion, migrationBlock: { migration, oldSchemaVersion in if (oldSchemaVersion < 22) { migration.enumerateObjects(ofType: Player.className()) { oldObject, newObject in // 用NSSet桥接拿到旧集合数据 guard let oldSet = oldObject!["preferredPositions"] as? NSSet else { NSLog("preferredPositionsSet is nil.") return } let preferredPositionsList = List<PositionClass>() // 可按业务需要排序,这里用PositionClass自带的order字段升序排列 let sortedPositions = oldSet.allObjects.sorted { obj1, obj2 in guard let order1 = (obj1 as? MigrationObject)?["order"] as? Int, let order2 = (obj2 as? MigrationObject)?["order"] as? Int else { return false } return order1 < order2 } // 写入新的List字段,Realm会自动处理对象关联 sortedPositions.forEach { posObj in if let pos = posObj as? PositionClass { preferredPositionsList.append(pos) } } newObject!["preferredPositions"] = preferredPositionsList } } }) Realm.Configuration.defaultConfiguration = config
补充说明
- 如果不需要自定义排序,可直接遍历
oldSet写入List,不需要做排序处理,不过原生Set是无序的,最终List的元素顺序无法保证。 - 不需要额外做对象的映射转换,Realm会自动处理迁移上下文中动态对象和实际Model类的关联。
内容的提问来源于stack exchange,提问作者SuperDuperTango
相关产品推荐
相关产品推荐

