Home

How to work with memory management in Objective-C

Working in Objective-C, unlike on the desktop, memory resources can be quite scarce on your favorite mobile platform. which makes it very important to not only guess but actually understand how to manage your memory within your application and code to ensure that the iOS does not 'kill' your application.

The iPhone cannot rely on garbage collection, something prevalent on desktop Objective-C. and indeed in most other object-oriented languages. You instead use reference counting which means you need to consciously be aware of who owns what object, when it should be alive and when it should die. Sounds kinda cruel huh?


OK, so working with objects, you own an object by manually instantiating it with either an alloc and then init. You an also use initWithSomething, which is a convenience method. The code would look like something below:

1
2
3
4
//first type
NSArray *anArray = [[NSArray alloc] init];
//convenience method
NSString *aString = [[NSString alloc] stringWithFormat:@"something..%d.", anumber];

 

 Instantiating using alloc and init, you are responsible for releasing the memory you have just allocated (that is, you just created a retaining count of 1) using the alloc, so you will also have to release it when you are done with it later, to give it a retain count of 0. The second example above would auto-release your object, so you don't manually release it as the object retain count would go below 0 and in fact go into -1. 

Working with Autorelease pool, you defer releasing the object until a later stage, relieving you of the responsibilities of releasing it and assigning the framework the responsibility of releasing it an an appropriate time. 
 
1
2
3
4
5
6
7
8
int main(void) {
    NSAutoreleasePool *pool;
    pool = [[NSAutoreleasePool alloc] init];
    NSString *string;
    string = [[[NSString alloc] init] autorelease];
    /* use the string */
    [pool drain];
}
 

The problem with autorelease pool is that you should not use it unless you need it , so due diligence is required. Your application's memory 
 
 
Your Job
- alloc
- copy
- retain

Not Your Job

- convenience (stringWithFormat etc)
 
usage would increase as autorelease isn't precise and efficient in memory management, so its always better for the programmer who knows when the object is needed to manually manage it. So in summation it is your duty to release an object based on the following scenarios:
Another thing to remember is that if your object is sitting within a delegate of another object, you need to make sure you set the object delegate property to nil before you call release, to ensure no ghost referencing occurs. 
The dealloc section in your code should override the super, so you don't call dealloc directly but
place the objects you want to release in the dealloc method. 
 
1
2
3
4
5
6
7
-(void) dealloc {
    [first release];
    [last release];
    [email release];
    [super dealloc];
}

 
You also have an opportunity to respond to memory warnings, and let you know that you have one chance to reduce your memory usage before the application will get killed by iOS. You place such code in the didReceiveMemoryWarningmethod, which is where you release any large blocks of memory.