Part of the Cocoa Paradigms node cluster


Some objects in Cocoa are not cleaned up and others are, thus it is up to the coder to ensure that objects are cleaned up after use to avoid memory leaks or objects which have been created are retained in memory when necessary

Cocoa's mechanism for cleaning up objects is for each object to have a retain count. When the count is zero the object is disposed of and the memory freed again. There is also a concept called the autorelease pool. Objects added to the autorelease pool will have their retain count decreased by one when the the pool is purged. The pool is usually purged on exit from a routine. Thus an object which you want to dump on exit can be given an autorelease message and will be cleaned up at some point in the future.

Object Creation

Cocoa classes have two types of methods.

The first type is a Class method which does not have to be called from an instance. Java programmers would call this a static object. These class methods are also referred to within Cocoa as convenience constructors. The important thing to realise about objects created with a class method is that they have a retain count of one but are also added to the autorelease pool on creation. Thus to keep hold of them on exit from a routine you must send them a retain message

	NSArray *temp =  [NSArray arrayWithObjects:object1,object2,nil];

This statement would return a NSArray with a retain count of 1 but which has also been added to the autorelease pool. So if this object was needed on exit from a routine the following code would have to be invoked.

	[temp retain];

The second type of method is an instance method which must be called from an instance of the object, which is done by sending an alloc method to the class and some form of init message. The init message is defined in the NSObject class and thus inherited by all Cocoa classes but most higher level classes have convenience init methods relating to their function e.g NSString has initWithContentsOfFile

	NSArray *temp =  [[NSArray alloc]  initWithObjects:object1,object2,nil];

The object temp is effectively the same object as the last example but has not been added to the autorelease pool and does not require a retain message to be sent to it.

When subclassing Cocoa classes never override the alloc method, instead create a custom init method to be invoked upon a alloc'ed object instance.

Object Destruction

When an objects retain count reaches 0 it is sent a dealloc message which releases any internal objects. When subclassing Cocoa classes you must override the dealloc method to also release any objects that have been created internally by your object in addition to calling dealloc on the superclass after releasing the subclasses own object.

So within the method implementation

- (void) dealloc
{
    [internal1 release];
	   [internal2 release];
	   ....
	   [super dealloc];
}

Memory management with Cocoa classes is relatively simple if you remember these prime things. First check the documentation for whether the Cocoa method you are attempting to use will retain the object that you are sending when needed (99% of them do) and second if you find yourself sprinkling retains and releases around without knowing why you are probably doing it the wrong way.