Memory Management in Objective C, Part 1
I interview a lot of people for jobs doing iPhone development, and it never ceases to amaze me how few people understand the memory management model in Objective C. I feel like there's something that can be a little better explained here, so I'm going to first do a post on the basics of memory management and then follow up with another post on how you can best organize your code to make things easy.
So first, the basics:
Memory Management in Objective C works on the principle of retain counts. An object exists as long as it has a retain count greater than 0. It is freed from memory whenever the count reaches 0. That's it. Nothing more complicated than that.
Ok, then the next question should be "how is the retain count changed?" There are three primary ways to modify the retain count available to you, the programmer, and a few others that are handled by the system. First, the modifications within your control:
Basic Calls
- retain: [object retain] you will add 1 to the count on object.
- release: [object release] will subtract 1 from the count on object.
- autorelease: [object autorelease] will subtract 1 from the count on object...just a little bit later, after the current run loop
All of that is pretty easy right? retain for +1, release for -1, autorelease for -1 at a slightly later date, and when we hit 0 get rid of the memory.
Ok, so what about creating objects? Well, there are a couple of simple rules in the standard SDK, and you should try to maintain those rules when you are writing code.
Initializers
- A method that includes the words init or copy is the same as _retain_, that is to say the object returned gets a +1 count
- Any other initialization method is the same as retain plus autorelease, so it has a +1 NOW, and will get a -1 later, after the run loop
Collections
The final piece is to know what happens when an object is added to an array, dictionary, or other foundation collection class. Luckily, that's pretty simple. When you put an object into a collection, the collection gives the object +1. When it's removed from the collection, the object gets -1.
Sooo...
That's actually all there is to the basics. You want to make sure that the object keeps a count of 1 or more until you want to get rid of it, Then you want to have a count of 0 so that the object will be freed. When that happens its dealloc method is called, which will (hopefully) get rid of all of _its_ objects.
These rules may sound obscure, but I'll make another post soon explaining how you can leverage these rules to build your classes in a way that makes memory management easy.
