Updated for Xcode 14.2
Swift’s classes can optionally be given a deinitializer, which is a bit like the opposite of an initializer in that it gets called when the object is destroyed rather than when it’s created.
This comes with a few small provisos:
func
with deinitializers – they are special.Exactly when your deinitializers are called depends on what you’re doing, but really it comes down to a concept called scope. Scope more or less means “the context where information is available”, and you’ve seen lots of examples already:
if
condition, that variable is not available outside the condition.for
loop, including the loop variable itself, you can’t use it outside the loop.If you look at the big picture, you’ll see each of those use braces to create their scope: conditions, loops, and functions all create local scopes.
When a value exits scope we mean the context it was created in is going away. In the case of structs that means the data is being destroyed, but in the case of classes it means only one copy of the underlying data is going away – there might still be other copies elsewhere. But when the final copy goes away – when the last constant or variable pointing at a class instance is destroyed – then the underlying data is also destroyed, and the memory it was using is returned back to the system.
To demonstrate this, we could create a class that prints a message when it’s created and destroyed, using an initializer and deinitializer:
class User {
let id: Int
init(id: Int) {
self.id = id
print("User \(id): I'm alive!")
}
deinit {
print("User \(id): I'm dead!")
}
}
Now we can create and destroy instances of that quickly using a loop – if we create a User
instance inside the loop, it will be destroyed when the loop iteration finishes:
for i in 1...3 {
let user = User(id: i)
print("User \(user.id): I'm in control!")
}
When that code runs you’ll see it creates and destroys each user individually, with one being destroyed fully before another is even created.
Remember, the deinitializer is only called when the last remaining reference to a class instance is destroyed. This might be a variable or constant you have stashed away, or perhaps you stored something in an array.
For example, if we were adding our User
instances as they were created, they would only be destroyed when the array is cleared:
var users = [User]()
for i in 1...3 {
let user = User(id: i)
print("User \(user.id): I'm in control!")
users.append(user)
}
print("Loop is finished!")
users.removeAll()
print("Array is clear!")
SPONSORED From March 20th to 26th, you can join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer!
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.