Objective C uses ‘reference counting’ as its main memory management technique (wikipedia.org/wiki/Reference_counting). Every object keeps an internal count of how many times it’s ‘needed’. The system makes sure that objects that are needed are not deleted, and when an object is not needed it is deleted. This may sound like automatic garbage collection (the way it works in Java, C#), but it is not. The main difference is that in automatic GC (Java, AS3 etc.), a separate chunk of code periodically runs in the background to see what objects are being referenced and which ones are not needed. It then deletes any unused objects automatically with no special handling required by the programmer (apart from making sure all references to objects are removed when not needed). In the reference counting method, the programmer has the responsibility of declaring when he needs the object and when he’s done with the object, and object deletion takes place immediately when the object is no longer used, i.e. reference count drops to zero (See the above wikipedia links for more on the matter).
Note: Objective C 2.0 also has an option to enable automatic garbage collection. However, garbage collection is not an option when developing for iPhone so its still important to understand reference counts, object ownership etc..
It’s important to understand the concept of object ownership. In Objective C, an object owner is someone (or piece of code) that has explicitly said “Right, I need this object, don’t delete it”. This could be the person (or code) that created the object. Or it could be another person (or code) that received the object and needs it. Thus an object can have more than one owner. The number of owners an object has is also the reference count.
Object owners have the responsibility of telling the object when they are done with it. When they do, they are no longer an owner and the object’s reference count is decreased by one. When an object has no owners left (i.e. no one needs it, reference count is zero), it is deleted.
You can still use an object without being its owner (using it temporarily), but bear in mind that the object might (and probably will) get deleted in the near future. So if you need an object long-term, you should take ownership. If you only need the object there and then (e.g. within the function that you received it, or within that event loop – more on autorelease pools later), then you don’t need to take ownership.
The main messages you can send an object (regarding memory management) are:
alloc (e.g. [NSString alloc]): This allocates an instance of the object (in this case NSString). It also sets the reference count to 1. You are the only owner of this object. You must release the object when you are done with it.
new (e.g. [NSString new]): This is basically a shorthand way of writing [[NSString alloc] init]. So same rules apply as alloc.
retain (e.g. [aString retain]): You call this when you are passed an existing object (memory has already been allocated for it elsewhere), and you want to tell the object that you need it as well. This is like saying “Ok, I need this object, don’t delete it till I’m done.”. The reference count is increased by one, and you are the new owner of this object (along with any other previous owners). You must release the object when you are done with it.
release (e.g. [aString release]): You call this when you are done using an object. You are no longer the owner of the object so the reference count is decreased by one. If reference count is now zero (i.e. no owners left), then the object is automatically deleted and the memory is freed, otherwise the object stays in memory for other owners to use. It is like saying “Right, I’m done with this object, you can delete it if no one else is using it”. If you are not the owner of an object, you should not call this. If you are the owner of an object, you must call this when you are done.
autorelease (e.g. [aString autorelease]). This means that you need the object temporarily, and does not make you an owner. It’s like saying “Ok, I need this object for now, keep it in memory while I do a few things with it, then you can delete it”. More on this later in the ‘autorelease pools’ section.
copy (e.g. [aString copy]): This creates a copy of the object (depending on how the copy message has been implemented for that object) and you become an owner of the new object.
So when dealing with Objective C pointers/objects, it’s important to remember to send the correct messages. The general rule of thumb is: If you own an object (allocate, retain or copy it), you release it. If you don’t own it (came via convenience method or someone else allocated it), you don’t release it.
An autorelease pool is an instance of NSAutoreleasePool and defines a scope for temporary objects (objects which are to be autoreleased). Any objects which are to be autoreleased (e.g. objects you send the autorelease message to or created with convenience methods) are added to the current autorelease pool. When the autorelease pool is popped (released) all objects that were added to it are also automatically released. This is a simple way of managing automatic release for objects which are needed temporarily.
E.g. You want to create a bunch of objects for temporary calculations, and instead of keeping track of all the local variables you define and then calling release for all of them at the end of your function, you can create them all withautorelease (or convenience methods) safe in the knowledge that they are going to be released next time the autorelease pool is popped. Note: there is a downside to this which I’ll discuss in the Convenience vs Explicit section.
Autorelease pools can be nested, in which case autorelease objects are added to the latest autorelease pool to be created (the pools are stacked in a Last In First Out type stack).
Example in the Autorelease, Convenience vs Explicit section.
Owning an object means explicitly declaring that you need it (by using alloc, new, retain or copy).
If you own an object, you need to explicitly declare that you are done using it (by using release).
Do not release an object if you are not the owner (i.e. you used autorelease on it, or it came via a convenience method, or it was simply passed in as a parameter or return value from a function).
Only retain an object if you will be needing it in the long-term. If you only need it there and then for the function you are in, you can safely use it without owning it.
Arrays, dictionaries etc. will take ownership of objects added to them (they call retain), so you do not need to explicitly retain when adding. If you own the object before adding to a collection, and you no longer need it outside of the collection, you must release it after adding.
If you are going to be using lots of temporary objects (autoreleased / from convenience methods) you may want to think about creating your own short-term autorelease pools to avoid temporary memory peaks. If you hit the memory limits on an iPhone, the app will just quit – it doesn’t matter if the objects taking up memory are no longer needed and are waiting to be released in an autorelease pool, it’s upto you to make sure you allocate and deallocate efficiently and in a timely fashion.
For more information make sure you read the official memory management docs, lots of important details there.
If you want to test for memory management the in that case you may use the tool named instruments which will provide you all the necessary details about your application memory wise. Here’s a image displaying the instrument tool in action
I hope you have understood the concept of memory management in case if you are having any queries then in that case kindly mail me at email@example.com until then Happy iCoding and have a great day you will get the PDF of this post here.