Search code examples
swiftswift-playground

A puzzle: weak reference not working in Swift 4?


I have created the following two classes in a Playground, and expect both of them to deallocate once they go out of scope (since references are weak). But to my surprise they do not!!! Can someone shed light on this puzzle? Thank you in advance.

Here is the Code:

class User {
    var name: String
    weak var phone: Phone?    
    init(name: String) {
        self.name = name
        print("User \(name) is initialized")
    }    
    deinit {
        print("User \(name) is deallocated")
    }
}

class Phone {
    let model: String
    weak var user: User?
    init(model: String) {
        self.model = model
        print("Phone \(model) is initialized")
    }
    deinit {
        print("Phone \(model) is deallocated")
    }
}

do {
    let user1 = User(name: "John")
    let phone1 = Phone(model: "iPhone7")
    user1.phone = phone1
    phone1.user = user1
}

print("Done")

and here is the output which shows that deinit() is not called, although the classes are going out of scope:

User John is initialized
Phone iPhone7 is initialized
Done

Why is that?


Solution

  • I believe this has something to do with how Playgrounds treat code. It doesn't have quite the same lifecycle and you can't expect variables to be deallocated once your code is done running.

    If you make your objects be optional, everything deallocates as expected:

    do {
      let user1: User? = User(name: "John")
      let phone1: Phone? = Phone(model: "iPhone7")
      user1?.phone = phone1
      phone1?.user = user1
    }
    
    User John is initialized
    Phone iPhone7 is initialized
    Phone iPhone7 is deallocated
    User John is deallocated
    Done