Search code examples
swiftautomatic-ref-countingweak-references

Two weak variables referencing each other in Swift?


I'm making another attempt today to try to understand retain cycles and weak references in Swift. Reading through the documentation, I saw the following code example where one of the referencing variables is marked as weak to prevent a retain cycle:

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment? 
    deinit { print("\(name) is being deinitialized") }
}

class Apartment {
    let unit: String
    init(unit: String) { self.unit = unit }
    weak var tenant: Person?             // <---- This var is marked as 'weak'
    deinit { print("Apartment \(unit) is being deinitialized") }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

john!.apartment = unit4A
unit4A!.tenant = john

john = nil // prints "John Appleseed is being deinitialized"
unit4A = nil // prints "Apartment 4A is being deinitialized"

Is there any problem with making both variable weak? That is, in the Person class, could I change the apartment variable to be weak so that I have

class Person {
    // ...
    weak var apartment: Apartment?  // added 'weak'
    // ...
}

class Apartment {
    // ...
    weak var tenant: Person?
    // ...
}

where there are two weak variables that reference each other.

I tested it out in the Playground and it seems to work ok, but is there any strong reason not to do this? It seems like in this case there is no natural parent-child relationship here.


Solution

  • You can do that. The only side effect is that you need to ensure that something else is retaining the people and the apartments. In the original code you just need to retain the people and the apartments (associated with people) will be retained for you.

    Strictly speaking the people aren't killed when the apartments are demolished and the apartments aren't demolished when the people die so weak references in this scenario make sense. It's generally better to consider the relationship and ownership model you want and then decide how to achieve that.