Automatic Reference Counting (ARC) and Memory Management in Swift

Automatic Reference Counting (ARC) and Memory Management in Swift

Introduction: 

Memory management is a key factor when we developing apps. If a program is using a lot of memory it can affect badly on your device making apps run slowly or even cause crashes. So for that in swift, you can work with Automatic Reference Counting (ARC) to keep your apps memory usage minimal. This doesn’t mean you can forget about the memory in your app but it does take care of most things for you.

It’s Important to note that ARC only works when working with classes, structs and enums are value types and therefore are stored differently in memory than classes which are stored and passed by reference.

Memory Problems

1- Your app uses too much of phone memory that causes your app to perform badly or can even crash or unexpected things can happen for example:

We have viewController, label or a tableView that loaded in memory and for some reason, if you forgot to use dequeuereusablecell the load all cells in the array, so use so this type of things can cause your app memory problem.

1- Adding something to the memory and then it never gets removed, like you have a view controller and that shows a popup and then popup closes but it never removes if you use that popup so many time then it use so much memory and never get released from memory.

2- You assign something to memory but unexpected remove from memory so then you try to access it or try to get the value of this then it results in a crash because this doesn’t exist in the memory anymore.                                     

So these are three different memory problems that are not all but for now, we are going with there.

How these things happen:

There are two different types in swift that you need to understand with,

1- Value types: This type can be like String, Int, Stuck, Enum, Array, Dictionary etc, for value type each instance (like String or Int) hold on its value and if you use it somewhere else it makes a copy of it and passes around your application.

2- Reference Types: Class is a reference type, for reference type instances, share a single copy of the data. So if you use or pass around your app then only one copy exists and you just passing a pointer or reference back to your class.

Ex: write this in Playground then run.

The job has a default value of 2, and Job first instance created called person. It will have a job of 2.

Now, create a new object called new and assign the previous object to this like as in the code above.

Now change the job of new to 5 and then print the job of both the instance. Both will print the number 5.

This is because the class is a reference type.

When will swift remove a reference type from memory?

When there are no more variables pointing to the reference type, Swift uses ARC to for this work.

How ARC works :

First, create a project with swift language and then select your ViewController.Swift file.

Add the following class to the bottom of your ViewController.swift:

This is very simple viewController and a class named MyClass, in DidLoad just initiate the class and create a couple more variables to pointing to the same class and then set them all to nil. See the MyClass code there is a definite function in there this is called right before the object remove from memory. So there is three-pointer (three reference count for MyClass), once you nil-all of them then you can see the print statements.

Now let’s see the memory problem 2 in which I mention adding something to the memory and then it never gets removed.

Add the following class to the bottom of you  ViewController.swift:

So here in this example, We are using two-class Job and Person, Job class have a variable named the person with the type of Person Class and similarly, Person class have a variable named job with type of Job Class, and we create some properties in DidLoad()

Variables – joe, dev that we create in DIdLoad(), they both have taken their Space and Memory and both having reference count 1.
joe is a Person type class variable and dev is a Job type class variable. and then we give joe a Job,

                                                         joe?.job = dev

So class var joe’s job variable will now reference of dev object coz of this Job have 2 reference count means two objects pointing to it.

Similarly with dev with Person Class,

                                                        dev?.person = joe

Now the person variable of dev point to Person Class so it also has 2 reference count.

So what happens if we did use their variables, and we set them to nil,

                                                               joe = nil

                                                              dev = nil

but still, there no deallocation print statement in console and Job and Person Class can’t be removed from memory because of the job and person variable point to them.

and this is called Retain cycle.

Retain Cycle :

Retain because apple holds on to these object and not let them go with the reference count > 1 and Cycle because of both object reference each other.

how you can detect these problems in Xcode?

By using Instruments tool.

In Xcode, Go to Product and click on profile,

 

Then a new tool will open name Instruments then select Leaks and choose.

Then you can see it point to our simulator and show next to our app as a target to run.

Then you just need to tap on the red button and it starts recording.

You can see the red cross sign showing two leaks, just tap on it, then you can see what objects are leaking like job and Person here.

You can look it a different way to like click on Leaks then it will show like three options (Leaks, Cycles & Roots and Call Tree).

Choose Cycles & Roots, then a cycle graph shows (Retain Cycle).

This is what actual problem with memory. They both pointing to each other.

How to fix a Retain Cycle:

Using Weak or Unowned reference instead of Strong reference, because weak or unowned reference does not increment the reference count.

Strong Reference :

It is by default if you make a reference without using weak or unowned then it is a strong reference.

Weak Reference:

For weak reference child may or may not exist if the parent removes from memory. It’s optional it can be set to nil.

Unowned Reference:

In this case, child definitely exists all the time but it is removed when the parent is removed so it is not an optional thing and we can’t set it to nil.

So let’s fix the Retain Cycle in Code.

I just make the job a weak variable then run the app, so it’s print the statement of deallocating Job and Person.

Now if we run the Instrument app then again record our app into it then we can see the green checkmark in place of the red cross. And its showing no leaks as well

This is how you can track and resolve the Retain Cycle and also can solve some memory leaks problems.

InnovationM is a globally renowned mobile app development company in India that caters a robust & secure Android app development, iOS app development, hybrid app development services. Our commitment & engagement towards our target gives us brighter in the world of technology and has led us to establish success stories consecutively. We are a leading iOS app development company in India & Android app development company in India.

Leave a Reply