What is ARC and how does it work in Swift?

Alexandre Freire
ClearScore
Published in
4 min readMar 3, 2020

Unlike other programming languages like Java or Kotlin, Swift doesn’t have a garbage collector. Instead, it uses a much faster technique called Automatic Reference Counting (ARC).

In most cases, this means you don’t have to worry about memory handling in Swift. It simply works, as if it were a garbage collector. In other words, ARC will automatically deallocate the piece of memory used by a class when it is not going to be used anymore.

How does ARC know if it can free the memory used by a class instance?

Very simple: ARC will count how many properties, constants or variables point to that given instance.

Each time you assign a class instance to one variable, the reference count (from now on, retainCount) increases by +1. If we assign the same instance to three different variables, its retainCount will be 3. Easy, isn't it?

var myVariable1: SomeObject = SomeObject()
var myVariable2 = myVariable1
var myVariable3 = myVariable1

Once the instance’s retainCount goes down to zero, ARC assumes this instance will never be reused and that it can be removed from memory.

👀 When you try to access to an instance which has already been removed from memory, your app crashes.

Hands-on the keyboard: Xcode

1. Increasing the reference count (retainCount)

Let’s suppose you have a class Author which represents the writer of a book.

class Author {

// MARK: Properties
let name: String

// MARK: Initialization
init(name: String) {
self.name = name
}

deinit {
print(“Author called \(name) is being deinitialized")
}
}

The Author class has an init method to create the object, and a deinit one which will be executed when the instance is removed from memory.

Now, you’ll create an Author? variable in order to assign either nil or an Author instance to it.

var author1: Author? = Author(name: “George R. R. Martin”)

Now, a strong reference is created between the author1 symbol and the Author instance. It's called a strong reference because it increases the retainCount by +1.

Now you’ll create two more variables and assign the same instance of author1:

var author2 = author1
var author3 = author1

With each new assignment, you’re creating a new strong reference, which adds +1 to the retainCount. At this point, the retainCount is 3:

2. Decreasing the reference count (retainCount)

Now you’ll do the opposite.

You’ll decrease the instance’s retainCount, assigning nil to some of our three author variables:

author1 = nil 
author2 = nil

Each time you do this, you decrease the retainCount by -1. So now the current retainCount value is 1 again:

Remember, ARC can only deallocate the instance if its retainCount is zero. Currently, it's still 1, because we can still access it through author3:

We can reach a zero retainCount by assigning nil to our author3 variable too:

author3 = nil// “Author called George R. R. Martin is being deinitialized"

Have you noticed what has been printed to your Xcode console? It was the code in the deinit method. This means ARC has freed the memory used by that class instance, since its retainCount is zero. In other words, there are no strong references pointing to that piece of memory, and therefore it's safe to remove it.

Conclusion

Although Swift doesn’t have a garbage collector, it uses another technique called ARC. It consists of counting the number of strong references pointing to a specific instance.

This technique is much faster than garbage collection and allows you to forget about memory handling in Swift in the majority of cases.

But there are times when you have to help your good friend Swift… In the next post, I’ll tell you one of these cases.

Meanwhile, if you liked this article, I invite you to follow me on Twitter at @xandrefreire.

Originally published at https://alexandrefreire.com

--

--