Reference cycles for classes

Two class instances which hold a strong reference to each other create a strong reference cycle that leads to a memory leak. That’s because each instance keeps the other one alive, so their reference counts never reach zero.

For example, our website has a lot of high quality programming tutorials and each of them is edited by a specific editor. You can model these tutorials with the following class:

class Tutorial { let title: String

let category: String let date: Date

var editor: Editor?

init(title: String, category: String, date: Date) { self.title = title

self.category = category

self.date = date

}

deinit {

print("Goodbye (title)!")

}

}

Each tutorial has a certain title, category, publishing date and assigned editor. The editor property is optional because you will set its value after you create the tutorial object with the class designated initializer. Remember from Chapter 15 that Swift calls the deinitializer automatically right before it releases the object from memory and its reference count becomes zero. You use string interpolation to print the tutorial’s title here.

Note: Type Date is part of the Foundation framework, so don’t forget to import it.

You’ve defined an editor for each tutorial, but you haven’t declared the Editor class yet. Here’s what it looks like:

class Editor {

let name: String let email: String

var tutorial: Tutorial?

init(name: String, email: String) { self.name = name

self.email = email

}

deinit {

print("Goodbye (name)!")

}

}

Each editor has a name, an email where you can reach her and an assigned tutorial. The tutorial property is optional because you will set its value after you create the editor object with the class designated initializer. You use string interpolation to show the editor’s name in the deinit method.

Now define a brand new tutorial for publishing and an editor to bring it up to the site’s high quality standards:

var tutorial: Tutorial? = Tutorial(title: "Memory management", category: "Swift", date: Date())

var editor: Editor? = Editor(name: "Ray", email: "[email protected]")

Note: You declare tutorial and editor as optionals because you will set them

both to nil soon.

Start the editing process by linking the two together:

tutorial?.editor = editor editor?.tutorial = tutorial

As the site’s editor-in-chief, you schedule the tutorial once the editor finishes editing it like this:

tutorial = nil editor = nil

Although you set both variables to nil, the objects deinitializers never get called and nothing gets printed to the console — bummer! That’s because you’ve just created a reference cycle between the tutorial and its corresponding editor. You don’t actually release the objects from memory, even though you don’t need them anymore.

Now that you understand how reference cycles happen, it’s time to break them. Weak references to the rescue! :]

results matching ""

    No results matching ""