Every software which wants to use a memory, before doing so, has to reserve an appropriate amount of space for itself first. Because of the fact, that nowadays apps are not independent and work within the operating systems that are responsible among the others, for the allocation of resources between active programs, such reserved memory space should be released as soon, as it’s no longer needed. This way, system can assign it to another process. When it not taking place, the running application uses more and more memory over time, which in consequence, leads to significant performance drops and very often the app is killed at the end by the system . This phenomenon is known as memory leak and in most cases, it’s a results of poorly written code. Get ready for the first part of the “Retain Cycles — The hidden trap of ARC” cycle. Enjoy!
A BIT OF HISTORY…
Objective-C — recently the sole and despite the growing popularity of Swift, still widely used within the Apple ecosystem language, has its roots back in the early 80s of last century. Modeled on Smalltalk and built as an extension of C which adds object-oriented functionality, Objective-C, in its primal form didn’t have any automated memory management system. Just like in C, it was the programmers job to allocate and release the memory used by the app.
This approach, while being pretty inconvenient, also had a few significant downfalls, such as:
- Instead of entirely focusing on the app functionality, the developer also had to consider how to design his own, in-app memory management, which usually had related consequences…
- Memory management code constituted a significant part of application source, reducing its clarity and making less readable
- The more complicated code, the easier for bug to creep into it. The mistakes were very common and usually led to:
- Memory leaks related to resources that should, but wasn’t released
- Crashes when resource was deallocated too quickly
To avoid drawbacks mentioned above, Apple equipped the Foundation framework which stands behind their Objective-C implementation, with semi-automatic, based on retain counting, memory management system called MRR — Manual Retain Release.
Fig.1 Graphical representation of retain count based memory management system.
a) Creating an instance of an A class object. The retaining reference is being created. Retain count increases to 1.
b) B and C class objects refer to the created object. Retain count is now 3.
c) C class object frees up the reference and the retain count decreases to 2. At the same time, D class object creates a copy of an object and retain the reference to this copy. Copying doesn’t create any reference to the original object. Retain counts stands still.
d) A and B class objects freeing up object references. Retain count is falling to 0.
e) The object is no longer needed and gets deleted. D class object frees up its copy reference, setting the counter to 0.
f) The copy also is no longer needed, both objects are disposed from the memory.
The way how MRR worked was based on owning, or in other words — retaining the object by any other objects which actually use it and counting those retains. At the moment when instance has been created or any retain reference was pointing to it, special counter has been incremented and opposite — decremented in the moment of particular reference release. When the retain count of such object has reached zero, it was a sign that it’s no longer needed and was disposed immediately (Fig.1). However, MRR was not a fully automatic mechanism. That was still up to programmer to decide, when the reference should be released. All the system cared about, was not deleting anything too soon, therefore a person which was writing a program, was concerned only in releasing useless references from the recent block of code, not the whole application memory management itself.
In practice, however, the set of rules and laws of retain and release of references to objects in MRR has proven to be so complicated, that to write a code which wouldn’t lead to memory leak, was a big hassle to the large amount of programmers. At WWDC in 2011, Apple announced that 90% of crashes of all apps available in the AppStore, was caused by memory related errors.
What is ARC ? How to properly deal with memory ? Wait for the second part of the “Retain cycles — the hidden trap of the ARC” coming soon.
Don’t forget to visit our blog, for more interesting articles — click here!
Article by Przemysław Foluszczyk — Appformation