In this tutorial, we’ll be covering Swift memory management and learn about Automatic Reference Counting (ARC) in Swift. It’s an essential concept and is useful in preventing memory leaks in our iOS Applications.

We’ll be covering the following concepts:

  • What is ARC and how does it work?
  • Resolving Strong Reference Cycles
  • Differences between strong, weak and unowned references
  • Strong Reference Cycles in Closures
  • Resolving Reference Cycles in Closures using Capture Lists

Swift Memory Management – Automatic Reference Counting

Automatic Reference Counting is an underlying tool that takes care of allocating and freeing memory for references. It keeps a track of the count of references for an object.

How does it allocate?
When an object is initialised, ARC assigns it a chunk of memory. That memory holds information about that object, such as its properties, constants, references it is linked to. Further reading – swift init function.

How does it deallocate?
ARC keeps a count of the number of references to the object. It cannot deallocate the object when there are references since that might lead to runtime crashes. Once the reference count is 0, it deallocates the object by calling the deinit() and frees up the memory.

Note: ARC and memory management do not guarantee to work perfectly in XCode Playgrounds as they do in XCode projects. Nevertheless, since the focus of this post is ARC and not iOS Applications, we’re using playgrounds below, just for the sake of convenience.

Swift ARC in Action

Let’s create a swift class and then instantiate it.

To deallocate the object, we need to remove the references.

In the above code, deinit block is run automatically by the ARC. You cannot call it manually.
We’ve created references of type Optional so that if they’re invoked in the future, it won’t cause a crash.
Setting the references as nil lets the ARC change the reference count.

Note: ARC is NOT a garbage collector. ARC can only clear memory if it unused. In some cases the programmer needs to help ARC to clear the memory and prevent memory leaks as we shall see in the next section.

Resolving Strong Reference Cycles

By default, the ARC creates a strong reference. Now we can have scenarios where there are reference cycles as shown in the code below.

Each of the classes has a reference to the other. Let’s initialise them.

This creates a strong reference between both the classes. Something that the below illustration rightly depicts.

Let’s see how the strong references impact the lifecycle of the objects.

We’ve set the references to nil, to let ARC deallocate them but it doesn’t happen.
Strong Reference Cycle is created in the above code that is a potential cause of memory leaks!

Before we get into resolving the strong references let’s look at other types of references.

strong, weak, unowned references

  • strong references are the standard type of references created by default.
  • weak references allow instance creations but do not add up in the reference count of the ARC. Typically a reference should be marked as weak when it has a shorter lifetime than the other reference.
  • unowned references are similar to weak references except that they’re used on references that have a longer lifetime than the other reference.
  • An unowned reference should be used only when you’re absolutely sure that the reference does exist there otherwise if it’s invoked on a nil reference it’ll crash.
  • A weak reference can be used when the reference is nil.

Resolving Strong Reference Cycles

We can resolve strong reference cycles in the above example by making any one of the references as weak or unowned references. Such references do not add to the reference count in the ARC.

Initialising the references and then setting then nil would now call the deinit statement.

Note: Setting unowned reference in the above example would cause a crash since unowned reference cannot be set to nil.


Resolving Reference Cycles in Closures using Capture Lists

Closures are reference types. Hence they can have a strong reference cycle created as shown below:

Let’s allocate and deallocate an object.

Because closures are reference types they create a strong reference cycle by capturing the self reference. Hence the reference count can never be zero.
Let’s try resolving this.

Capturing Lists

We can use self as a weak or unowned reference inside the closure as shown below.

We explcitly pass a list passing an unowned reference of self.

As we known from Closures, the parameters are separated from the return type by the in keyword.
With that the strong reference cycle in closures is resolved.

That’s all for quick roundup on swift memory management and automatic resource counting feature.

Reference: Apple Docs

By admin

Leave a Reply

%d bloggers like this: