Important concept series in iOS Development

ARC(Automatic Reference Count) and Memory Management

ARC ( Automatic Reference Counting) is memory tracking management system of Swift language. It does so by deleting the objects from the memory after (job is done) its reference count is zero.

When creating the instance of a class, Swift remembers that instance is being referenced precisely once. If you assign it to another variable, Swift will increment the reference count to 2, meaning two variables pointing at the same object. If you now destroy the first variable (perhaps it is used in some function block and that function ended executing its tasks), Swift takes the reference count back down to 1. All this matter because as long as the reference count is greater than 1, the object stays alive.

According to ARC Memory management, an object can be one of reference strong, weak or unowned type with a variable, will be discussing more about them further, for now, if the object doesn't have any key word before let statement then by default it will be with strong reference.

Like this :

let name = String() -> the variable name has strong reference.

Let's demonstrate it with code:

Screen Shot 2021-05-31 at 16.57.18.png

So you see here we are constructing Person class and its instance assigned to strong reference to var ulugbek with parameters name, age, nationality. Then when we set the var ulugbek to nil, the deinit will be called deallocating the memory created for that obejct automatically by ARC management.

Now, let's do something different : Screen Shot 2021-05-31 at 17.03.42.png

Wait, Wait... Where did deinit print "Person: Ulugbek removed" go? we made ulugbek nil right? you know why? because, according to ARC memory management object with at least one strong reference will not be freed/deallocated. So that ARC memory management, the ulugbek object was not deallocated even though we made it nil, because the variable ulugbekReference has a strong reference to an instance were ulugbek was pointing to, so the strong reference count of object were ulugbek was pointing too was not zero hence not deallocated or freed, if we make ulugbekReference = nil then we will see the log of deinit Person: Ulugbek removed.

That was the brief ARC intro.

Now coming to actual problem, nightmare :) Strong/Retain Cycle, do not worry, once we will get into that, you will actually understand so easily.

As we know each time we declare a class property by default it has a strong reference to object which it is pointing to unless we specify something, so when can a strong cycle appear?

Let's just say, objectA has strong reference with objectB and vise versa.

1_o4FAAeJiX90eK33V7GEeOA.png

Let's understand it with a code, we will declare one more class iPhone and use Person class itself

Screen Shot 2021-05-31 at 17.39.25.png

So that's how should look like our classes, Person having 4 properties with strong reference name, age, nationality and iphone and iPhone class has 3 properties serialNumber, model and owner as we can see the property owner is of type class Person.

Now, let's use and demonstrate how the strong cycle occurs.

Screen Shot 2021-06-01 at 10.11.54.png

What!! where is the strong cycle? I created the instance person, created an instance of iphone, assigned person?.iphone = iphone then I nil both person and iphone, you know both got removed as I can see in the log, so where is the strong cycle?

Actually, the strong cycle is not created yet, in person we made iphone to point the instance iphone which is a strong reference relation with iphone, but as we can see in the iPhone class there is an entry called owner which we did not assign to person yet, if we now do iphone.owner = person before freeing them, you see :

Screen Shot 2021-06-01 at 10.17.41.png

Why didn’t the log print now? we made both person and iphone nil, so? so here we made a crime of making strong reference cycle between person and iphone.

  1. person object has a strong reference to iPhone which is pointing to iphone

  2. iphone object has a property owner with a strong reference pointing person

Thus they both became a retain cycle, means person will be retained by iphone and iphone will be retained by person so they both don't get freed or deallocated.

Screen Shot 2021-06-01 at 10.40.02.png

How can we resolve this? there comes the saviour weak reference !

A weak reference is a reference that does not keep a strong hold on the instance it refers to and so does not stop ARC from deallocating the referenced instance. This behaviour prevents the reference from becoming part of a strong reference cycle. You indicate a weak reference by placing the weak keyword before a property or variable declaration.

That’s what apple document speaks about weak reference, let’s try breaking the above retain cycle with the weak keyword.

Let person still have a strong reference with iphone we will make the owner property of iPhone weak by just adding the keyword weak before var as shown below.

Screen Shot 2021-06-01 at 10.47.53.png

So here you see both iphone and person being deallocated by just putting the weak before var and yes we did break the retain cycle with the weak reference type.

That's all for now, we understand what is ARC and strong cycle and retain cycle in Swift. We know now how to break the retail cycle after execution our object. In the next post, I will try to make the difference between weak and unowned keywords and dive into retail cycle, with great examples, so that we have strong visualization when and in what condition we use weak and unowned.

See you soon :)