Lorenzo Rossi Lorenzo Rossi - 4 months ago 24x
Swift Question

Single inverse relationship in Realm models

I'm developing a simple iOS app to learn Swift and I'm using Realm.
As far as I know, in Realm inverse relationships are achieved with a

property which is a collection containing all objects linked to that one.

Consider this example from the Realm Documentation:

class Person: Object {
// ... other property declarations
let dogs = List<Dog>()

class Dog: Object {
dynamic var name = ""
dynamic var age = 0
let owners = LinkingObjects(fromType: Person.self, property: "dogs")

In my model, I know that each
instance will only have one owner since every dog, when created is added to only one

Now I'd like to have a
owner: Person
property in the
class that references to its only owner to make the code more intuitive and simpler (instead of having to write
every time) while keeping the lazy-loading behavior (they are lazily loaded, right?).
I don't know how expensive it is to query the "Linking Objects", but since there will be many "Dogs" around, I think it would be better not to access them on object initialization.

For now these are the solutions I could think of:


class Dog: Object {
let owner: Person = LinkingObjects(fromType: Person.self, property: "dogs").first!


class Dog: Object {
private let owners = LinkingObjects(fromType: Person.self, property: "dogs")
lazy var owner: Person = {return self.owners.first!}()


class Dog: Object {
lazy var owner: Person = {
return LinkingObjects(fromType: Person.self, property: "dogs").first!


class Dog: Object {

private let owners = LinkingObjects(fromType: Person.self, property: "dogs")
var owner: Person {
return self.owners.first!


I don't think "solution 1" is lazy loaded and, as in "solution 2", the
won't be "auto-updating", however this shouldn't be a problem since in my case a
won't ever change owner.

What would you recommend to have a single inverse relationship in Swift?


The only way is 3. Neither 1 nor 2a, 2b don't work.

Because at present LinkingObjectscan only be used to initialize a property of type LinkingObjects. Realm reads class definitions and all properties when initializing to define data schema. In the code of 1, owner property is treated as just Person property.

2a and 2b also don't work. Because Realm doesn't support lazy properties. Also 2b uses LinkingObjects in the wrong way same as 1.

So, only 3 works as expected.

See also... https://github.com/realm/realm-cocoa/issues/3525#issuecomment-216920757