Home > Development, Objective-C, iPhone Development > Free Me from Your Shackled Embrace!

Free Me from Your Shackled Embrace!

December 15th, 2008

The Problem of Memory Management
Mac OS X Leopard introduced garbage collection, however this feature is missing on the iPhone. Therefore, it is still necessary to manage your own memory through what is known as reference counting.

Reference Counting or Retain Count
Reference counting is actually a very simple idea and has been around for a long time. However, it has a tendency to get tedious when a lot of objects and references are involved.

In Objective-C, every object has a retain count (or a reference count). When an object is created, its retain count is 1. When an object is released, its retain count is 0. When the retain count is 0, the object is deallocated and the memory is freed. As you can see, this is a very simple concept.

We can work through a simple example.

1
2
3
[sam alloc];          // sam has retain count of 1
cindy = [sam retain]; // sam has retain count of 2
[sam release];        // sam has retain count of 1

When the code finishes, sam still has a retain count of 1, so the memory will not be freed. This is because cindy is being clingy and not setting sam free. So in order for sam to be free, we need to release sam one more time.

1
[sam release];      // sam has retain count of 0

AutoRelease
But there is a problem. What if you have a function that returns a newly allocated string? Consider the method below.  

1
2
3
4
5
6
- (NSString)getName
{
   NSString *name;
   name = [[NSString alloc] initWithFormat:@"Robot No. %d", 23];
   return name;
}

In the method above, name will have a retain count of 1 because of alloc and initWithFormat. And when we call the method (or send a message in Objective-C lingo), the caller would generally do this.

1
2
NSString *robotName = [self getName];
[robotName retain];

We retain the value returned by getName because we do not want the object to deallocate before we are done with it. However, this creates a memory leak because the retain count is at 2. We can call [name release]; inside getName right before it returns, but that would cause the retain count to go to 0 and the object would not exist anymore (because it would have been freed).

Meet the NSAutoReleasePool. We can modify the method above to:

1
2
3
4
5
6
7
- (NSString)getName
{
   NSString *name;
   name = [[NSString alloc] initWithFormat:@"Robot No. %d", 23];
   [name autorelease];
   return name;
}<span style="font-family: 'Lucida Grande'; line-height: 19px; white-space: normal;"> </span>

Take note of the line “[name autorelease];“. This line adds this object to the auto release pool. Meaning, the object will not be freed immediately, but rather sometime later in the future. All the objects in the auto release pool are released when the drain message is sent to the auto release pool.

Somewhere near the beginning of your code, you will have the line below.

1
NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];

When the autorelease message is sent to an object, it is added to this pool. When [pool drain] is called, all the objects in the pool are sent the release message.

Remember
The thing to remember is that objects created with alloc, new, copy, mutableCopy or if any function is called that retains the object and increases the retain count, you will have to call a release for each one of those retains.

Any other method will have a retain count of 1, and the object will be added to the auto release pool so you don’t have to worry about those as long as the pool is drained.

Circular Retains
One final note of caution. You must remember to avoid situations where a circular link is created among objects when object A retains object B and object B retains object A. This creates a circular link and creates a retain cycle.

If you enjoyed this post, make sure you subscribe to my RSS feed!

Development, Objective-C, iPhone Development , , , , ,

  1. Yongrim
    December 15th, 2008 at 18:47 | #1

    You gotta love Java’s garbage collector after reading this. You can imagine what kind of work went into creating a solid garbage collector. Fascinating topic in and of itself.

  1. No trackbacks yet.