Deinitialization
Deinitialization releases resources that need custom cleanup.
A deinitializer runs right before a class instance is deallocated. Use the deinit keyword to write one, similar to init for initializers. Deinitializers are only for classes.
How Deinitialization Works
Swift deallocates instances automatically when they're no longer in use, freeing up memory. It uses automatic reference counting (ARC) for this. Usually, no manual cleanup is needed. But if your class handles custom resources—like opening a connection—you might need to close it before deallocation.
Each class can have only one deinitializer. It takes no parameters and doesn't use parentheses:
deinit {
// Perform cleanup here
}Deinitializers run automatically before deallocation. You can't call them manually. Subclasses inherit superclass deinitializers, which run after the subclass's deinitializer. Superclass deinitializers always execute, even without a subclass deinitializer.
A deinitializer can access and use the instance's properties, like checking a resource ID to release it properly.
Deinitializers in Action
Here's an example with two classes: Library and Member, for a simple book-lending system. The Library class tracks a fictional inventory of books, limited to 500 in circulation. It's a single shared instance, using class properties and methods.
class Library {
static var booksAvailable = 500
static func lend(books requested: Int) -> Int {
let booksToLend = min(requested, booksAvailable)
booksAvailable -= booksToLend
return booksToLend
}
static func returnBooks(books: Int) {
booksAvailable += books
}
}The Library tracks available books with booksAvailable. It has lend(books:) to check and provide books (returning fewer if needed) and returnBooks(books:) to add them back.
The Member class represents a library user with borrowed books in booksBorrowed:
class Member {
var booksBorrowed: Int
init(books: Int) {
booksBorrowed = Library.lend(books: books)
}
func borrowMore(books: Int) {
booksBorrowed += Library.lend(books: books)
}
deinit {
Library.returnBooks(books: booksBorrowed)
}
}A Member starts with borrowed books from the library (possibly fewer if unavailable). The borrowMore(books:) method adds more. The deinitializer returns all books on deallocation.
var memberOne: Member? = Member(books: 5)
print("New member joined with \(memberOne!.booksBorrowed) books")
// Prints "New member joined with 5 books"
print("Library has \(Library.booksAvailable) books left")
// Prints "Library has 495 books left"An optional Member variable allows tracking if the member is active.
memberOne!.borrowMore(books: 10)
print("Member borrowed 10 more, now has \(memberOne!.booksBorrowed) books")
// Prints "Member borrowed 10 more, now has 15 books"
print("Library has \(Library.booksAvailable) books left")
// Prints "Library has 485 books left"The member borrows more books.
memberOne = nil
print("Member left the system")
// Prints "Member left the system"
print("Library now has \(Library.booksAvailable) books")
// Prints "Library now has 500 books"Setting to nil deallocates the instance, triggering the deinitializer to return books.