iOS Memory Management Made Easy

Programming languages, such as Java, provide automatic garbage collection. On the other hand, developing applications for iOS platform requires that programmers explicitly handle memory management. Many programmers who are new to iOS development or whose primary programming experience is in Java or similar languages often struggle with memory management in their iOS applications. The main problems related to memory management in iOS are:

  1. Bad access caused by accessing already freed data
  2. Memory leaks caused by not freeing data that is no longer required

There are a few rules which one can follow in order to make sure that the above two problems never occur in an application.

1.     Always release objects you own

Here it is appropriate to define the concept of ownership. You take the ownership of any object you create. The object created (and consequently owned) by you are those that you “alloc”, “new”, “copy”, or “mutableCopy”. For example:

Window *aWindow = [[Window alloc] init];
// Do stuff with window
[aWindow release];

2.      Never release an object that you don’t own

You don’t own any object that you didn’t “alloc”, “new”, “copy”.  It is important to explicitly state that objects you get by calling factory (or convenience) methods should not be released (since they are owned by the object whose factory method was used).  For example:

NSString *name = [[NSString alloc] init];
NSString *message = [NSString stringWithString:@”Hello World!”];
// Do stuff
[name release];
// No release is required for message

3.     Always override NSObject dealloc method in your class

If you create a class (inherited from NSObject or its descendent), you must also override the dealloc method of the NSObject and release all the fields of the class. (Note that fields of primitive types such as NSInteger do not need to be released.) See the example below:

@interface Person : NSObject {
NSString *name;
NSString *email;
}
@end

@implementation Person {
- (id)init {
if ((self = [super init])) {
...
}
return self;
}

- (void)dealloc {
[name release];
[email release];
[super dealloc];
}
@end

You should also never invoke any object’s dealloc method directly. You should also invoke the dealloc of the super class inside your dealloc method.

4.     Don’t release objects you mark for autorelease

If you create any object andput it in autorelease pool, you should never try to release it. An example follows:

NSArray *theArray = [[[NSArray alloc] init] autorelease];
// Do something
// Don’t release theArray

Autorelease is often used when an object is created in a function to be returned to the caller. In this case, the function can’t release the object because otherwise, the caller won’t be able to access the object. When autoreleasing objects, neither the function nor the function caller has to worry about releasing the object. For example:

- (MyObject *)getObject {
return [[[MyObject alloc] init] autorelease];
}

5.     Never use accessor methods during init

You should never use accessor method to set a property in the object initializers.

-(id)init {
if ((self = [super init])) {
// Do not use self.name = ..., rather use name = ...
name = [[NSString stringWithString:@"iOS Developer"] retain];
}
return self;
}

For initializers with parameters, you can do something like the following:

-(id)initWithName:(NSString *)newName {
if ((self = [super init])) {
// Do not use self.name = …, rather use name =
name = [newName copy];
}
return self;
}

You should also release the property in the dealloc method.

-(void)dealloc {
[name release];
[super dealloc];
}

By following the above rules consistently throughout your application, you can avoid memory management issues. You should nevertheless, use Clang Static Analyzer and Instruments to memory leak proof your applications.

  1. No comments yet.

Leave a reply

 
 
 


− three = 4