Realm's documentation on to-many relationships declares its List<Dog>
property using let
:
class Person: Object {
// ... other property declarations
let dogs = List<Dog>()
}
Why is this List<T>
property declared using let
when other Realm property types are declared using dynamic var
?
List<T>
properties should be declared using let
as Realm is unable to intercept assignment to these properties. Assigning to List<T>
properties won't result in your changes being persisted to the Realm file. By declaring the property using let
rather than var
you enlist the Swift compiler to detect code that won't do what you intend.
Instead of assigning to List<T>
properties you should mutate the existing value of the property via the methods that are part of the RangeReplaceableCollection
protocol to which List<T>
conforms.
For instance, to add a new dog:
person.dogs.append(lassie)
Or to replace the existing dogs:
person.dogs.replaceSubrange(0..<person.dogs.count, with: [fido, spot])
Realm model classes automatically implement getters and setters for your persisted properties that access the underlying database data. In order to provide these getters and setters, your properties must be declared with the dynamic
modifier. This modifier asks Swift to dynamically dispatch accesses to the properties via getters and setters rather than directly accessing the member at compile time. The dynamic
modifier comes with a significant limitation: it is only supported for types that can be represented in Objective-C. This is because Swift's dynamic dispatch is built on top of the Objective-C runtime. It is this limitation that prevents Realm from intercepting assignments to List<T>
properties.