Friday 3 December 2010

iPhone Tutorials - Start with Objective-C


If you want to program on Macintosh or iPhone, first you have to learn Objective-C. Objective-C is very different from C++ or Java, because it follows the "other" way for Object Oriented Programming, the Message Passing.
With message passing, you can easly implement some designs patters, such as the delegate, but you'll see it when I'll talk about UITableViews. First, you'll see how Message Passing is more expressive and readable than C/C++/Java Methods.
Now, let's image to implement a simple (and classic) ComplexNumber class. First, on a file called ComplexNumber.h we'll write the class interface.

//ComplexNumber.h
@interface ComplexNumber: NSObject{
    double real;
    double imaginary;
}

//---constructor
-(id)init;

@property(nonatomic)  double real;
@property(nonatomic)  double imaginary;

//---Add
-(void)Add:(ComplexNumber*)other;

@end

Quiet easy, right? Class' members are defined between braces and methods (or messages) follows immediatly. Class Interface is closed between @interface and @end keywords. id type is a pointer to an unspecified object, something like a "pointer to anything". It's usefull expecially in delegate design pattern.

@properties are "syntactic sugar". They help you to implement easily getters and setters for members. With this trick we'll can write

complex.real=3.0f;

Parameters inside the @property specify how the variable is passed (e.g. by reference or by copy). Because real and imaginary are base-datas, we haven't to specify the way.

A method is defined according with this protocoll

-(type_returned) MethodName:(parameter_type)parameter_name;

So, a method called "HelloWorld" wich returns nothing (void) and wich accepts a NSString* (OpenStep strings) will look like

-(void)HelloWorld:(NSString*)string;

Now, let's create another file called ComplexNumber.m and let's implement all methods

#import "ComplexNumber.h"

@implementation ComplexNumber

//--- implementing properties
@synthesize real;
@synthesize imaginary;

/**
* Constructor
* a constructor always calls first constructor from 
* mother class and returns the object itself. Between
* [super init] and [return self] we set values for
* all object members
-(id)init{
    self=[super init];
    real=0.0f;
    imaginary=0.0f;
    return self;
}


/**
 * Add
 * add param other to this ComplexNumber
 */
-(void)Add:(ComplexNumber*)other{
   real+=other.real;
   imaginary+=other.imaginary;
}
@end

Now, our class is over. Let's trying it on a main.m.

int main(int argc, char** argv){
    ComplexNumber* one=[[ComplexNumber alloc] init];
    ComplexNumber* two=[[ComplexNumber alloc] init];

    one.real=3.2f;
    one.imaginary=1.8f;

    two.real=4.0f;
    two.imaginary=2.2f;

    [one Add:two];

    // NSLog is the OpenStep equivalent
    // of printf. You can declare a NSString* without using
    // a constructor, using the synthax:
    // NSString* s=@"Hello world";
    NSLog(@"Now one is %.1f+i%.1f",
                                one.real,
                                one.imaginary);

    [one release];
    [two release];

    return 0;
}

This is our first Objective-C program: a simple ComplexNumber class. It has many problems, such as it lacks a parametrized constructor (something like c=new Complex(real,imaginary) in C++ or Java) a toString method and a method to set real and imaginary in one shot. I shall show you how improve this class in next tutorial.

No comments: