Chapter 11. Memory Management

Memory management is very important, but easy, in GNUstep. Here are some good articles:

  1. Memory Management in Objective-C
  2. Memory Management 101
  3. Very simple rules for memory management in Cocoa
  4. Hold Me, Use Me, Free Me
  5. Accessor methods and (auto)release: conclusion
  6. Memory Management with Cocoa/WebObjects

GNUstep offers some good macros to ease the coding related to memory management. Take a look at NSObject.h for ASSIGN(), RELEASE(), RETAIN(), etc.

The most common way to handle release/retain is this:

@interface MyObject: NSObject
{
  id myData;
}
-(void) setMyData: (id) newData;
-(id) myData;
@end

@implementation MyObject
- (void) setMyData: (id) newData
{
  ASSIGN(myData, newData);
}

- (id) myData
{
  return myData;
}

- (void) dealloc
{
  RELEASE(myData);
}
@end

Basically it works for me. ASSIGNCOPY() can also be used to copy object. Always use [self setMyData: newData] to set myData, or at least use ASSIGN(myData, newData). Don't use myData = newData. By this way, you don't need to worry about the memory management.

In some case, I will use mutable classes because they are thread-safe. For example:

@interface MyObject: NSObject
{
  NSMutableArray *myArray;
} 
-(void) setMyArray: (NSArray *) newArray;
-(NSArray *) myArray;
@end 

@implementation MyObject
- (id) init
{
  myArray = [NSMutableArray new];
}

- (void) setMyArray: (NSArray *) newArray
{ 
  [myArray setArray: newArray]; 
} 

- (NSArray *) myArray 
{ 
  return myArray; 
} 

- (void) dealloc 
{ 
  RELEASE(myArray); 
}
@end

Mutable classes cost more resources. But it is a lazy way to avoid problems.

Also be aware of the return values from GNUstep classes. Some are autoreleased. For example, [NSArray arrayWith...], or [@"A string" stringBy...]. If you release them again, the application usually crashes. And remember to retain them if you want to use them later, and release them in -dealloc. It's safe to use ASSIGN() in this case. For example:

ASSIGN(myString, [@"A string", stringBy...])

ASSIGN() will handle all the details. Again, once you use ASSIGN(), release it in -dealloc.