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:
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 :
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.
Let's understand it with a code, we will declare one more class iPhone
and use Person
class itself
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.
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 :
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.
person
object has a strong reference toiPhone
which is pointing toiphone
iphone
object has a propertyowner
with a strong reference pointingperson
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.
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.
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 :)