Friday, May 13, 2011

Creating a custom object in Objective-C

 

I started learning Objective-C and Cocoa about a month ago. I’m going to be posting here how I see the language from my perspective as a C# .Net developer….. so lets start!

 

The first thing that I want to know when learning a new language, is how to create my own custom object. In order to create a class you should derive from NSObject. This object has all the smarts for memory management and other basic functionality.

 

The second thing is to know is what type of object to create. I like taking pictures, so I’m going to create my own camera object. An Objective-C class is typically separated into two files.

 

 

The first file Camera.h contains the interface for the class.

 

 

@interface Camera : NSObject {

    //instance variables

    double aperture;

    double shutterSpeed;

  

}

 

//method declarations.

-(id) init;

-(void) focus;

-(void) takePicture;

 

@end

 

Okaaaay what’s up with those minus signs? Turns out that the minus signs represent instance methods. In contrast,  the + sign is used for static methods.  Notice I need to derive from NSObject explicitly. If I didn’t, my camera class would need to reinvent the wheel, and I’m sure I don’t want to do that. The method naming convention is also different from C#, the convention is: method names and variable names start with a lower case letter. Class naming seem familiar however, class names start with an uppercase letter.

 

The second file, Camera.m contains the implementation.

  

#import "Camera.h"

 

@implementation Camera

 

//method implementations

 

-(id) init{

    self = [super init];

    if(self){//always use this pattern in a constructor.

         aperture =2.8;

         shutterSpeed = 1/60;

    }

   return self;

}

 

-(void) focus{

//focus mechanism

}

-(void) takePicture{

//take picture functionality

}

@end

 

No need to mention NSObject again, I just need to implement the methods I declared in the interface.I also need to import the Camera.h file. Notice init returns an id type. The id type can hold a reference to any object, kind of like the System.Object in .Net.  Now somewhat less intuitive, but very important,  is the need to add the following initializer pattern inside the constructor.

 

    self = [super init];

    if(self){

       //Implementation of constructor.

    }

   return self;

 

The keyword super is used to call the base class constructor. What would happen if init returns nil ? In Objective-C sending message to nil has no effect at runtime! How cool is that? Using a null object in .Net is a common source of bugs.

 

I can now create my own camera like this:

 

Camera *myFirstCamera = [Camera alloc];

[myFirstCamera init];

 

The [ ] notation will probably hurt your eyes, but it’s how you call methods in Objective-C. The Camera class calls the static method alloc to allocate memory for the object. Then, the init ‘constructor’ method is called to initialize the member variables of the camera object.

 

Usually you group both calls in one line like this:

 

Camera * myFirstCamera = [[Camera alloc] init]; //buy the camera

 

Now we can use our camera…

 

[myFirstCamera focus];

[myFirstCamera takePicture];

//..

[myFirstCamera release];//clean up...

No comments:

Post a Comment