Hey folks! Today we continue with swift interview topics. In the previous article, we talked about protocols, generics, and closures.
You can find the article here.
Our focus today is memory management. We will talk about the general outlines of the questions asked in the interviews. To learn in detail, be sure to read the swift document.
Okay, let’s start.
Automatic Reference Counting (ARC)
You are probably familiar with the concept of ARC. Automatic Reference Counting (ARC) allows us to track and manage an app’s memory usage. ARC automatically handles the allocation and deallocation of memory.
Reference counting applies only to instances of classes. Structures and enumerations are value types, not reference types, and aren’t stored and passed by reference.
Although ARC works automatically, we need to pay attention to the relationships between objects to avoid memory leaks. If you are a junior developer, that’s something you mostly ignore.
Okay, I just talked about something called memory leak. We’ll talk about that shortly. Let’s first look at how ARC works.
How ARC Works?
When we create a new instance of a class, memory allocates space for it. The allocated memory is where the properties of the instance are kept. The memory continues to be used until this instance is no longer needed. If not required, the allocated memory is freed and used for other purposes.
Strong References
ARC does not deallocate an instance as long as there is at least one active reference to that instance. When we assign a class instance to a property, constant, or variable, that property, constant or variable, makes a strong reference to the instance. This Reference is called a strong reference because it holds that instance tightly. As long as the strong reference remains, ARC does not allow deallocation.
A property is strong by default.
In Swift, the memory instance is only released when the reference count is 0. To manually release we need to assign nil. This is why strong references are never 0.
Let’s take a look at an example.
The Person class contains a name and a home variable. We have defined the variable Home as an instance of the House class. The House class contains an address and owner variable. We defined the owner variable as an instance of the Person class.
Next, we created a person named “Damla” and a house with the address “221 B Baker Street”. The reference values of these objects are stored as the damla and damlasHouse variables.
Finally, we mentioned that damla’s home is damlasHouse and that damlasHouse is owned by damla. With these codes, the reference values of both objects are linked to the other. In this way, the damla object can access the address of the house and the damlasHouse object can access who the host is.
As a result of this strong connection, both objects remain in memory, and if one object dies, it does not cause the other to remain in memory. Therefore, for example, if the damla object dies, the damlasHouse object still remains in memory and the address of the house is accessible.
Weak References
Weak references are used when we want to completely dispose of the referenced instance. A weak reference does not strongly hold the instance it refers to. Therefore, the weak reference makes it possible to relocate the sample while referring to it. Changes the ARC reference value to nil when the sample is repositioned. Properties are defined as variables, as this value may change during execution.
Now let’s take a look at the weak reference version of the example we saw for strong reference.
The Person instance still has a strong reference to the House instance, but the House instance now has a weak reference to the Person instance. Once we break the strong reference held by the damla variable, there will be no more strong references to the Person instance. This will prevent the other from remaining in memory if one object dies.
Unowned References
Unowned references are similar to weak references. Unowned references do not strongly hold the instances they refer to.
In fact, the point we will focus on here will be the difference between weak and unowned.
We use unowned when we want an instance to have a longer lifetime. So what does this mean? We would expect a weak reference to become nil at some point in its lifetime. So weak references are actually optional. We expect unowned references to always have a value. Marking a value as unowned does not make it optional. Unowned references are non-optional.
Unowned references do not guarantee that the referenced object remains in memory. Therefore, if the House object is cleared from memory, a runtime error occurs for the Person object, as there is no value for the owner variable. Therefore, when using unowned references, it must be guaranteed that the referenced object has already been created and will remain in memory.
In the table above you can see how strong, weak and unowned references should define properties as constants or variables.
Now let’s move on to another important concept.
What is Retain Cycle?
If we want to allocate an object from memory, that object’s reference value must be 0. Suppose we have two objects. Object A and Object B. Suppose Object A and Object B are strongly connected to each other. The fact that objects are strongly connected to each other means that the reference value will always be 1. A retain cycle occurs in this scenario because the compiler cannot release these two objects.
Now is the time to talk about memory leak.
How does a memory leak occur?
Pieces of memory allocated for an object but never released cause a memory leak. These objects occupy memory forever and cause rapid use of all memory reserved for the application. The operating system forces the application to close and the app crashes.
Retain cycle causes memory leak.
This means that the memory cannot be reused unless there is some intervention. At this point, it is very important to understand the concept of ARC and how it works.
I guess that’s all I’m going to talk about. I can clearly say that they like to ask questions about this subject.
Thank you for reading, see you soon!