Swift中如何向Realm的List属性追加通用元素?
这个问题我之前也碰到过!核心原因是Realm的List是强类型的泛型集合,它不支持把具体的List<你的模型类>直接转成List<Object>——泛型协变在这里不生效,所以直接强制转换或者当作List<Object>调用append肯定会炸。
给你两个靠谱的解决方案,都能绕过泛型类型的限制:
方案一:用KVC+ListBase动态操作List
Realm的所有List都继承自ListBase这个抽象基类,它提供了通用的append(_:)方法。我们可以通过KVC(键值编码)动态获取到目标List,再转成ListBase来添加元素。
修改你的函数,加上List属性的名称参数(比如你要往listObject的cars这个List属性里加元素,就传"cars"),然后调整代码:
func save(elements: [String : Any], realmClassName: String, realm: Realm, listObject: Object, listPropertyName: String) { guard let properties = realm.schema[realmClassName]?.properties else { print("找不到对应Realm模型的属性信息") return } guard let namespace = Bundle.main.infoDictionary?["CFBundleExecutable"] as? String else { print("获取App命名空间失败") return } guard let realmClass = NSClassFromString("\(namespace).\(realmClassName)") as? Object.Type else { print("无法初始化Realm模型类") return } do { try realm.write { for element in elements { let object = realmClass.init() // 给模型属性赋值 for property in properties { if let value = element[property.name] { object[property.name] = value } } realm.add(object) // 关键:通过KVC拿到List并添加对象 if let list = listObject.value(forKey: listPropertyName) as? ListBase { list.append(object) } } } } catch { print("保存数据失败:\(error.localizedDescription)") } }
方案二:用Mirror反射定位List属性
如果你不想用KVC,也可以通过Mirror反射遍历listObject的属性,找到对应的List:
// 在事务内添加完object之后 let mirror = Mirror(reflecting: listObject) for child in mirror.children { guard let list = child.value as? ListBase, let propertyName = child.label else { continue } // 匹配你要操作的List属性名 if propertyName == listPropertyName { list.append(object) break } }
额外注意事项
- 我修正了你代码里未定义的
name变量(应该是realmClassName),别忘检查。 - 一定要确保新创建的
object类型和List存储的类型一致,不然Realm会抛出类型不匹配的错误。 - 所有修改Realm数据的操作(包括添加到List)都要放在写事务里,我已经把代码包在
try realm.write里了,这样更安全。
内容的提问来源于stack exchange,提问作者RFG
相关产品推荐
相关产品推荐

