Objective-C is an object-oriented programming language, and is a layer over the C programming language. This means that if you know how to write C, there are only a few syntax changes to learn.
In this section, we will look at how we can implement classes and instantiate objects in Objective-C. If you are unfamiliar with object-oriented programming, see Objective-C concepts.
BASIC SYNTAX
In objective C, code is contained within functions, and a function is composed of several statements. Each statement is terminated by a semicolon. For example, a simple function to add two numbers may look like this:
int add (int a, int b)
{
int c;
c = a + b;
return c;
}
This sample has the following lines:
The function definition (which returns an int, is named add, and takes two parameters, both of which are integers).
The opening function brace
A variable declaration
An assignment statement
A return statement, which returns the value of c to the calling function/
The closing function brace
For flow control, Objective-C uses:
for (<initial>;<condition>;<increment>)
while (<condition>)
do … while (<condition>)
switch (<condition>)
Each statement behaves in the same way as C; they will continue execution of a loop until the condition is false (or in the case of switch, jumps to the appropriate case label and continues to the end) and can be exited early using the break or continue keywords.
Objective-C does not implement functions by default. Instead, they need to be declared by using the #include or #import preprocessor statements.
WRITING CLASSES IN OBJECTIVE-C
Writing an Objective-C class requires a few design decisions before we start writing any code. Say we are writing a class to represent a point called Point in a two-dimensional plane.
We need to ask ourselves two questions:
What data do we need to store and use? This relates to the instance variables we need to declare.
What operations do we need to perform? This relates to the methods we need to define.
For this example, we’ll use double variables for the x and y coordinates. We’ll define a method to get both coordinates, and we’ll define a method to get their distance from the origin.
THE INTERFACE
#import <objc/Object.h>
@interface Point : Object
{
@private
double x;
double y;
}
– (id) x: (double) x_value;
– (double) x;
– (id) y: (double) y_value;
– (double) y;
– (double) magnitude;
@end
Let’s examine what each element of this interface means.
#import <objc/Object.h>
@interface Point : Object
The @interface line says that we begin the declaration of the Point interface. We inherit from another class called Object. Objective-C provides you with a generic class, calledObject. The Object class provides a set of methods that provide key functionality for an object to be used and recognized by the Objective-C runtime. Every object in Objective-C inherits from Object. As in C, we need to include Object’s header file, Object.h, before we can use the set of methods declared in the header.
The word import means that we only include the file once. This solves problems like recursive includes.
{
@private
double x;
double y;
}
Anything between the braces in an interface declaration specifies the instance variables that the class has.
The @private line is a visibility modifier: it says that the instance variables after it are private, i.e. they are accessible only from the class that declares them. It is good practice to mark all your instance variables private: they contain the state of an object and they should never be changed except by the object itself.
– (id) x: (double) x_value;
The declarations for the methods come after the instance variables. This is a declaration for the method to set the x value. It’s common Objective-C style to name the setter method with the same name as the variable it’s setting.
The dash specifies an instance method (we’ll look at these later). Then comes the name for the method (this method is called x: – note the colon), and the colon signifies an argument, called x_value, and is of type double.
The cast on the x_value argument is necessary, because unlike C, the default type is id, and not int. The type id is very special—it is a type that can hold any object whatsoever. The first cast is not strictly necessary, but should be used for clarity. The first cast tells us that the method x returns an object back.
– (double) x;
This is another method named x (no colon), but it returns a double. This is the specification for the method that gets the value of the x variable. There is no conflict with the previous method because the types are different, and the previous method takes one argument whilst this takes none.
@end
After all the methods and instance variables are specified, this symbol marks the end of the declaration.
The interface specification goes in a .h file—a header file. It’s customary to call the file after the class, so we would create a file called Point.h.
THE IMPLEMENTATION
#import “Point.h”
#import <math.h>
@implementation Point
– (id) x: (double) x_value
{
x = x_value;
return self;
}
– (double) x
{
return x;
}
– (id) y: (double) y_value
{
y = y_value;
return self;
}
– (double) y
{
return y;
}
– (double) magnitude
{
return sqrt(x*x+y*y);
}
@end
This is the implementation for the Point class. We implement the methods in the interface defined above. Let’s have a look at each element of the implementation in turn.
#import “Point.h”
Again, we import Point’s interface, just as we do in C.
@implementation Point
This is a marker that identifies the beginning of the implementation.
– (id) x: (double) x_value
{
x = x_value;
return self;
}
This is a typical method implementation. We can use the x variable directly without having to declare it since it is already declared in the interface, and is accessible only to the methods of this class. The behaviour, in general, is like an ordinary C function. Here we assign the value of the argument x_value to the instance variable x.
The function then, returns the entire, current object as modified. The keyword self represents the current object.
– (double) x
{
return x;
}
Here is the simple method to get the value of the x variable. We simply return it.
The behaviour for the other methods should be similar to those above. The @end keyword ends the implementation.
The implementation specification goes in a .m file. It’s customary to call the file after the class, so we would create a file called Point.m.
USING THE OBJECTS
Since Objective-C comes from C, we write a main function to make use of the class that we just created. Here’s one typical main function.
#import “Point.h”
#import <math.h>
#import <stdio.h>
int main(void)
{
Point *point = [Point new];
[point x:10.0];
[point y:12.0];
printf(“The distance from the point (%g, %g) to the origin is %g.n”,
[point x], [point y], [point magnitude]);
return 0;
}
Let’s examine what happens here.
#import “Point.h”
#import <stdio.h>
We import the interface to Point so we can use it. We import stdio.h so we can use printf.
Point *point = [Point new];
This is a typical Objective-C method call:
Point *point declares, technically, a pointer to an instance of type Point. Actually, it may be best to think of this merely as a variable holding a Point object, but keep the pointer idea in mind.
[Point new] calls a method called new. The first half before the space represents the object we call the method on. The second half is the method name and arguments. The newmethod is called a class method, because it doesn’t do something with respect to an instance of a class, it does something with respect to the class itself. The new method allocates memory and initializes the object, making it ready for use. There is no need to explicitly delete an object, as Objective C keeps track of the number of references to a given object, and deallocates them as necessary.
NOTE: The new method is shorthand for alloc and init and may not always be available. If it is not, the object can be initialized and made ready for use in the following fashion: [[Point alloc] init]
[point x:10.0];
[point y:12.0];
These are some typical instance method calls. We call point’s method x: and y:. In Objective-C terminology, we say that we send point a message to apply to the method x:.
These messages assign point’s x and y variables. Recall that the x: and y: methods had in them return self;. This means that we can chain the two messages together, as follows:
[[point x:10.0] y:12.0];
The message [point x:10.0] returns an object, point, with its x variable set. Then on that object, the outer message assigns its y variable.
printf(“The distance from the point (%g, %g) to the origin is %g.n”,
[point x], [point y], [point magnitude]);
The printf statement has in it the method calls [point x], which returns the value of the x variable for printing, [point y], which does the same for the y variable for printing, and [point magnitude] which calculates the distance and returns that value.
Discover more from mycodetips
Subscribe to get the latest posts sent to your email.