13.5. Dropping Unused Objects

Most Swarm objects will respond to the drop message. This message causes them to execute whatever commands are necessary to remove themselves from memory. When objects created by user-created classes are no longer needed, they should be dropped as well. It is vital, therefore, to customize the drop method of a user-defined class so that all objects created within the object are explictly dropped.

In the Point class, the super class's drop method is inherited from SwarmObject. However, if we were to tell a Point object to drop, it would not automatically drop the dynamically allocated memory referred to by the pointer position. Similarly, any other Swarm objects allocated in the Point object would not be dropped. In order to be sure these are dropped, the drop method should be overridden and customized. When that method is overridden, it is vital to make sure the super class's drop method is executed. That is the reason that the Point class's drop method begins with [super drop]. Any objects that have been allocated in Point, such as the memory devoted to the variable position, should be taken care of at that stage. Any Swarm objects that have been created, such as lists, list indexes, or other objects should be dropped in the drop command.

Many users think that there ought to be an "automatic" way to drop all objects that exist inside an object. This would certainly be convenient, since rewriting a drop method to make sure all objects are correctly disposed of can be tedious and possibly error-prone. While there is no such automatic object-dropping facility, there is a way to design Swarm code that comes close.

To make sure that all objects inside another object are dropped, users might consider a strategy that uses Zones more carefully. Instead of following the Zone usage examples provided by most Swarm applications, consider instead creating agents inside separate memory zones. When a zone gets the drop method, it does drop all objects inside it!

Here is how such a program might be designed. Suppose that agents are to be created in the model swarm by a for loop. The usual approach would create the objects in the model swarm itself, using the Zone of the model swarm.

//in the buildObjects method of ModelSwarm.m
for(i=0;i < numAgents;i++)
 {
   id agent;
   agent=[Agent createBegin: self];
   agent=[agent createEnd];
   [agentList addLast: agent];
 }

Suppose that instead of creating the instances of the class Agent inside the model swarm itself, we create a Zone object each time through the loop, and then create the agent inside that zone. For example,

//in the buildObjects method of ModelSwarm.m
for(i = 0;i < numAgents; i++)
{
  id agent, newZone;
  newZone=[Zone create: self];
  agent=[Agent createBegin: newZone];
  agent=[agent createEnd];
  [agentList addLast: agent];
}

The Agent class might create all kinds of objects, and we could use the method described above to write a drop method for the Agent class. However, this second approach has simplicity on its side. If it is necessary to drop an agent, instead of using the command [agent drop], we instead find out what the agent's zone is, and drop that:

//first, suppose you want to remove an agent named "agent".  
//Remove references to agent from the list
[agentList remove: agent];
//Then drop that agent's zone
{
  id agentZone;
  agentZone=[agent getZone];
  [agentZone drop];
}
//This could be achieved with a single line: [[agent getZone] drop];

This Zone-oriented approach might bring a bit of peace of mind because it eliminates the danger of a memory leak that may result when an agent is dropped but the objects inside it are not.