Memory management is very important, but easy, in GNUstep. Here are some good articles:
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.