如何在Realm模型中正确添加@Persisted修饰的[String?]数组
问题原因
Realm持久化属性对类型有严格约束,两种错误写法分别踩了不同的规则红线:
- 第一种
@Persisted修饰原生Swift可选字符串数组的写法:@Persisted属性包装器仅支持实现了_Persistable协议的类型,标准库的[String?]即Array<Optional<String>>没有实现该协议,因此编译器直接抛出类型不匹配错误。 - 第二种
dynamic修饰原生数组的写法:dynamic是依赖Objective-C运行时实现的旧版持久化写法,Swift的可选值数组无法桥接到Objective-C运行时,因此Realm不会识别该字段为持久化属性,打印模型时自然不会展示该字段,也不会做持久化存储。
正确实现方案
Realm集合类型必须使用SDK自带的专用类型,不能直接使用Swift原生数组、集合、字典类型。根据你使用的Realm版本选择对应写法即可:
方案1:Realm 10.0及以上版本(推荐)
10.0及以上版本的Realm已经原生支持List集合存储可选基础类型,直接使用List<String?>声明属性即可:
class RealmDataBaseClass: Object { // ... 其他属性 @Persisted var arrayOfCheckInDays = List<String?>() // ... 其他属性 }
注意List是引用类型,声明时如果直接初始化空列表不需要额外重写构造方法,后续修改元素直接调用append、remove、replace等List自带方法即可,不要给属性重新赋值新的List实例。如果业务代码需要使用原生[String?]类型,直接通过Array(arrayOfCheckInDays)即可快速转换。
方案2:Realm 10.0以下版本兼容写法
旧版本不支持List直接存储可选基础类型,可以通过包装一层轻量Object模型实现:
// 包装用的轻量模型 class CheckInDayEntity: Object { @Persisted var dayValue: String? } class RealmDataBaseClass: Object { // ... 其他属性 @Persisted var arrayOfCheckInDays = List<CheckInDayEntity>() // ... 其他属性 }
这种写法全版本兼容,存取时需要多访问一层dayValue字段即可。
注意事项
- 所有Realm持久化的集合属性,统一使用
List(有序可重复)、MutableSet(无序不重复)、Map(键值对)三种SDK自带类型,不要使用Swift原生集合类型,避免出现无法持久化、类型不匹配的问题。 - 新代码优先使用
@Persisted属性包装器写法,不要继续使用老旧的dynamic写法,后者对Swift类型的兼容度很差,后续版本也会逐步淘汰。
内容的提问来源于stack exchange,提问作者fonzyara
相关产品推荐
相关产品推荐

