Two weak variables referencing each other in Swift?

后端 未结 3 1319
滥情空心
滥情空心 2021-02-13 20:13

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

3条回答
  •  野趣味
    野趣味 (楼主)
    2021-02-13 20:34

    To augment the accepted answer, here is a concrete example which demonstrates the behavior.

    Try this is a Playground:

    class Person {
        let name: String
        init(name: String) { self.name = name }
        weak 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") }
    }
    
    class Test {
        var person: Person
        init() {
            person = Person(name: "Fred")
            let unit2B = Apartment(unit: "2B")
            person.apartment = unit2B
            unit2B.tenant = person
            print(person.apartment!.unit)
        }
    
        func test() {
            print(person.apartment!.unit)
        }
    }
    
    func go() {
        let t = Test()
        t.test()  // crashes here!
    }
    
    go()
    

    At the time of init in class Test, the apartment that has been created is retained by the local variable unit2B. When init is finished, the apartment will be deallocated because there are no longer any strong references holding it, so the program crashes when test is called because person.apartment is now nil.

    If you remove the weak from weak var apartment in class Person, then this example won't crash because the apartment created in init is retained by the person who is retained by the class property person.

    The other way to fix the example is to make unit2B be a property of class Test. Then the apartment would have a strong reference holding it so unit2B wouldn't be deallocated after init.

    If you remove weak from both weak var apartment in class Person and from weak var tenant in class Apartment, then the example won't crash, but neither the Person nor the Apartment will be deallocated because of the retain cycle created by two objects holding strong references to each other.

提交回复
热议问题