Automatic Reference Counting

Introduction

Welcome to Lesson 1 of Swift Memory Management. You will learn the definition of the term “memory” in the context of the Swift Programming Language. By the end, you will understand how objects are initialized and destroyed by the operating system.

Problem

Deallocate and allocate objects with ARC

What is Memory

There are primarily two places to store data: 1. RAM or 2. Hard Disk. The term “memory” refers to management of space of RAM.

Automatic Reference Count - 图1

When an object is initialized, it is physically stored on RAM. Since the space is limited, the object should be removed when unused. The process is known as deallocation. You will learn how to deallocate objects using ARC, Automatic Reference Counting.

Design Passport

Create a class called, Passport. It contains two properties whose types are Human?and String. The Human class defined below.

  1. class Passport {
  2. var human: Human?
  3. let citizenship: String
  4. init(citizenship: String) {
  5. self.citizenship = citizenship
  6. print("\(citizenship) passport generated")
  7. }
  8. deinit {
  9. print("I, paper, am gone")
  10. }
  11. }

Design Human

Create a class called, Human. It contains two properties whose types are Passport? and String.

  1. class Human {
  2. var passport: Passport?
  3. let name: String
  4. init(name: String) {
  5. self.name = name
  6. print("\(name) generated")
  7. }
  8. deinit {
  9. print("I, \(name), gone")
  10. }
  11. }

Important: The deinit block runs automatically when the object no longer exists on its RAM.

Create Instances

Let us create an object without var or let.

  1. Passport(citizenship: "Republic of Korea")
  2. // "Republic of Korea passport generated"
  3. // "I, paper, am gone"

Ironically, the Passport object has been deallocated immediately after initialized. Let us create a variable that has a reference to Passport.

  1. var myPassport = Passport(citizenship: "The Mars")
  2. // "The Mars passport generated"

The Passport object is not deallocated. The phenomenon is due to Automatic Reference Counting. If an object has a reference, it stays. Conversely, there is no reference, the object gets deallocated automatically.

The Only Rule: If the reference count reaches zero, the object is deallocated.

Create Instances

Create two instances one with Human and the other one with Passport.

  1. var bobby: Human? = Human(name: "Bobby")
  2. var passport: Passport? = Passport(citizenship: "Republic of Korea")

Let us visualize the relationship.

Automatic Reference Count - 图2

Deallocate

You may set the relationship as nil.

  1. bobby = nil // deallocated
  2. passport = nil // deallocated

Automatic Reference Count - 图3

Important: When you set the variable as nil, you destroy the reference, not the object itself. The object is deallocated usually since the reference count reaches zero.

Discover Retention Cycle

However, we do not live in an ideal world. Even if you set the reference as nil, the object may stay in the RAM forever.

Create Instances

Create two instances: bob and myPassport.

  1. var bob: Human? = Human(name: "Bob")
  2. var myPassport: Passport? = Passport(citizenship: "Republic of Korea")

Create a relationship between the instances

  1. bob?.passport = myPassport
  2. myPassport?.human = bob

Let us visualize the relationship

Automatic Reference Count - 图4

The Human object has two references from bob and Passport. The Passport object has two references from myPassport and Human.

Deallocation

Let us set the relationship from bob and myPassport as nil. However, it is not deallocated.

  1. bob = nil // Human not deallocated
  2. myPassport = nil // Passport not deallocated

Automatic Reference Count - 图5

The Human object’s reference count is one from the Passport object. The Passport object’s reference count is one from the Human object. There is no way to deallocate both of them. The current situation is called, retain cycle or memory leak.

So solve the problem, you may set one of the relationship as weak which does not increase the reference count.

  1. class Passport {
  2. weak var human: Human?
  3. let citizenship: String
  4. }

Automatic Reference Count - 图6

Currently, the Human object has one reference count from bob only since the weak reference does not increase the reference count.

Deallocation

Let us attempt to deallocate the objects.

  1. bob = nil
  2. // "I, Bob, gone"

The Human object is deallocated since the reference count reaches zero.

Automatic Reference Count - 图7

You may destroy the Passport object

  1. myPassport = nil
  2. // "I, paper, am gone"

Automatic Reference Count - 图8

Important: There is no such thing as retain cycle in structs and enums.

Source Code

5001_intro_memory_management.playground

Resources

Make Memory Management Great Again

Conclusion

First, you’ve learned the definition of Memory Management in the concept of the Swift Programming Language. Always think about the fridge as well as the sour milk. You only want foods that are nice and fresh. Second, when you set the variable as nil, it does not mean destroying the object. It means removing the reference. Last, it’s all about the reference count. Make it zero if you wish to deallocate.

In the following lesson, you will learn a possible retain cycle that might occur when you use the delegate pattern. Make sure you review the previous lesson before proceed.

Note: Learn Swift with Bob is available on Udemy. If you wish to receive a discount link, you may sign up here.