3.2. Objective C Basics

3.2.1. The id Variable Type

The variable type that is added by Objective C is id. It is the default type for objects in Objective C. Think of this as a special variable type (which is actually a pointer to a special data structure - namely the object)

All objects can refer to themselves by using the label self. This is necessary if, in the code that defines the object, the programmer wants to make the object execute one of its methods. For example, suppose an object has a method called updateRecords. If a command

[self updateRecords];

is received, then the updateRecords command will be executed, presumably to cause the updating of instance variables.

All objects can refer to superclass by the name super. For example:

[super updateRecords]

3.2.2. Interface File: Declaration of a Class

If you look in a directory where some Objective C Swarm code resides, you will see files in pairs, such as ObserverSwarm.h and ObserverSwarm.m, ModelSwarm.h and ModelSwarm.m, and so forth. The "h" files are the interface files (commonly called header files), while the "m" files are the implementation files

Figure 3-1. Objective C Basics

As illustrated in Figure 3-1, the interface declares the name of the class and the name of its superclass. Then it gives a list of variable types and names enclosed by braces ({}), and then the names of the methods that the class can implement are listed. The variables defined in this list can be used by any of the methods defined for the class. (These are often called "ivars", short for instance variables.)


Example 3-1. Objective C class

@interface Bug : SwarmObject 
{
  int xPos, yPos;
  int worldXSize, worldYSize;
  id foodSpace;
}
- setX: (int) x Y: (int) y;
- step;
- (return_type)look: (direction_type) d;

@end
Declarations of instance variables and methodsSub classSuper classInstance Variablesdeclares method called set that takes two argumentsdeclares a method called step.declares a method called look that takes one argument of type direction_type and returns an argument of type return_type.

3.2.3. Implementation File: Defining a Class

Each implementation file--the .m that parallels the .h -- must import its header file. For the header file described above, called Bug.h, for example, the implementation looks like:

#import "Bug.h"
@implementation  Bug
- setX: (int) x Y: (int) y
{
 xPos = x;
 yPos = y;
 return self;
}
- step
{
 // body 
 return self;
}

- (return_type)look: (direction_type)d
{
  return_type returnval;
  // body of method
  return returnval;
}

This example shows a number of important features. First, note that the method look specifies a return type, (return_type). In this example, return_type would have to be replaced by a variable type, such as int, float, or whatever, and returnval would have to be a variable of that type. When that method is called, the receiving code must be able to accept a return of that type. In contrast, the method step does not specify a return type. That means the default type, id, is returned. The code that calls this method must be consistent with that return type.

The return self command is used for two types of situations. Suppose the method is not intended to create any output, but rather it changes some instance variables. For example, suppose there is some program that creates an instance of Bug called aBug. Then that object is sent this message:

[aBug step]

In such a case, the code that calls that method does not expect anything back from it (except itself). Rather than fuss with void as the return type, as one might in C, one can simply return self.

In another case, one might actually intend to return the object to a list or another object. In such a case, return self will also be appropriate. If one is making a list of collected bugs, for example, then the usage of return self in that method will give back aBug id to the calling program. To be perfectly concrete about it, suppose the calling code has a list called collectedBugs. Then using the addLast notation from the Swarm collections library, the command to add aBug to the list after being collected might look like this:

[collectedBugs addLast: [aBug look:
aDirection]];

3.2.4. C Functions vs. Objective C Methods

For readers who are already familiar with C, perhaps a comparison of C functions against Objective C methods is in order. Since Objective C is a superset of C, an Objective C method can include any valid C commands. A method can return any type that a C function can return, and in addition it can an id (which, strictly speaking, is a pointer to an object).

In the abstract, an Objective C method has this structure:

- (type)name: (type)arg1 argName2: (type)arg2 
{
 (body)
 return returnval;
}

In comparison, a C function would look like this:

(type)name((type) arg1,(type) arg2)) 
{
 (body)
 return returnval;
}

The code in body of an Objective C method can be exactly the same as in C. The two languages are compared side-by-side in the following example, which describes how a function rand_move() might compare to a method rand_move:. Of course, each of these assumes there are other functions and variables that can be accessed, but the contrast in style should be informative.


Example 3-2. C vs Objective C

C Objective C
void rand_move(int i) {    

 int tmp_loc;

 do{
 tmp_loc=get_rand_loc();
 } while(val[tmp_loc]!=0);

 val[location[i]]=0;
 val[tmp_loc]=i;
}
- rand_move: p 
{
  id loc;

  do{
   loc=[self getRandLoc];

  } while([world at: loc]!=nil);

 [p moveTo: loc];
 return self;
}