为什么Realm建议使用"let"声明List <T>属性?

bda*_*ash 3 realm swift

Realm关于to-many关系的文档List<Dog>使用let以下方法声明其属性:

class Person: Object {
    // ... other property declarations
    let dogs = List<Dog>()
}
Run Code Online (Sandbox Code Playgroud)

为什么在List<T>声明使用let其他Realm属性类型时声明了此属性dynamic var

bda*_*ash 7

List<T>应声明属性,let因为Realm无法拦截对这些属性的赋值.分配给List<T>属性不会导致您的更改持久保存到Realm文件.通过声明属性let而不是var您使用Swift编译器来检测不能执行您想要的代码.

List<T>您应该通过作为符合协议一部分的方法来改变属性的现有值,而不是分配给属性.RangeReplaceableCollectionList<T>

例如,要添加新狗:

person.dogs.append(lassie)
Run Code Online (Sandbox Code Playgroud)

或者更换现有的狗:

person.dogs.replaceSubrange(0..<person.dogs.count, with: [fido, spot])
Run Code Online (Sandbox Code Playgroud)

为什么?

Realm模型类自动为访问底层数据库数据的持久属性实现getter和setter.为了提供这些getter和setter,必须使用dynamic修饰符声明属性.此修饰符要求Swift通过getter和setter动态调度对属性的访问,而不是在编译时直接访问该成员.该dynamic修正配有显著的局限性:它仅支持可以在Objective-C表示的类型.这是因为Swift的动态调度建立在Objective-C运行时之上.正是这种限制阻止了Realm拦截List<T>属性的赋值.