Swift, like other programming languages such as Java, has its own system of memory management. This means that the programmer does not have to worry about the allocation and deallocation of memory and can worry about the actual high level implementation of the app. While this is a nice feature of a programming language, it is important to understand what is going on behind the scenes because automatic memory management in Swift can cause problems.
ARC Memory Management
Object creation in swift comes in three parts, creation of a reference, memory allocation for an object of a particular size, and instantiation of that object in the allocated space. If you are familiar with a programming language like C or Objective-C, you know that you have to perform each of these steps manually. Some people find this tedious which is why high level programming languages such as Swift and Java are popular. Luckily for us, this is all done automatically in Swift! However, it can also cause some problems that are often overlooked by programmers that do not understand how the language implements the ARC Memory management system.
ARC stands for Automatic Reference Counting and it is a system that is meant to keep the amount of memory usage minimal, which is important when programming for a device like a phone, whose memory resources are limited.
How it works
ARC Memory Management works by keeping a tally of how many references there are to a specific object in memory. Once there are no references left to that object, the object is deallocated to conserve space.
Take for instance,
Here we created a new UILabel object in memory and a reference to it named “label”. Automatic reference counting then notes that there is one reference to this object.
Object Reference Lifecycle
Object references are alive throughout their scope. What this means is that as soon as a variable’s scope is no longer active, the reference is deleted. Right now the scope of the example above is not really defined, so we would assume that the reference would live until the app is terminated.
If we were to put the exact same line of code in some sort of scope, the reference will be deleted during the runtime of the app at the end of the scope.
Here we are putting the creation of the object and reference inside of the brackets, normally called a scope, and the reference is only alive for the duration of that scope. Then, once that reference is deleted after the exit of the scope, the ARC memory management system detects that there are no more references to that object and deletes it from memory!
This is a very efficient and nice way for memory to work in programming and allows there to be multiple references to an object, knowing that the object will not be deleted until there are no more references to it.
Problem to be aware of
While this is a really nice system that makes sense, it is important to understand that this is happening behind the scenes because the ARC Memory Management System causes some problems in Swift.
Let’s say for example we have two objects, an owner and a dog. Each keeps a reference to the other as a property.
In this case it is possible that the Dog and the Owner maintain a strong reference cycle to each other, and therefore the reference counter would be at 1 for each one. This means that neither object would ever be deleted!
Weak Variables
One tool that is given to us in Swift is weak variables. Weak is a modifier to a reference that allows the reference to not be involved in the lifecycle of the owner’s object. This concept of ownership cycles allows us to safely create a weak reference cycles between objects without worrying about the objects never being deleted.
Here, in the declaration of our Dog class, the reference to the owner is declared as weak and therefore, when it comes the time for the Owner object to be deleted, ARC can do so successfully because there isn’t a strong ownership cycle between them!