Monday, December 15, 2008

Objective-C: creating a basic class

Objective-C is an object oriented implementation added to C. Apart from objects, everything is C works in Objective-C. Here, I try to document what a class looks like, and what it all means. Bear in mind that I am just starting to learn objective-c myself, so, wouldn't recommend anyone using this class in a production environment :)

Objective-C separates a class into its declaration and implementation. It is not enforced, but is a best practice to put the declaration in a header (.h) file, and implementation in a .m file. See notes embedded in the source code below for details.

Geek.h (Class declaration)

#import <Foundation/Foundation.h>

// An Objective-C class is declared using the interface tag
// The parent of this class is declared after the ":"
// Best Practice tip: Always inherit from NSObject, when you don't have anything else to inherit from.

@interface Geek : NSObject{
// All data members go inside the braces
NSString *name;
int level;
}

/*
* All supported messages (functions) are declared before the @end tag
* Best-Practice tip: All messages that initialize the class should begin with "initWith".
* This provides the reader with good information.
* a.k.a. declared initializers
*
* You don't really have to declare messages that this class will override.
* It would be good idea to do so, in the interest of readability
*
* All data types are enclosed in brackets.
* id is a special type that means "myself". Any method that declares (id) as return type, must return "self"
*
* Methods don't really have a name. If you want, you could consider the first
* parameter as the name itself.
*/
- (id) initWithName:(NSString *)name level:(int)level;

// As a general rule of thumb, getters usually don't begin with "get"
- (NSString *)name;
- (int)level;
- (void) setName:(NSString *)name;
- (void) setLevel:(int)level;

@end // Marks the end of the interface tag


Geek.m (class definition)

#import "Geek.h"

// implementation of this class starts from here
@implementation Geek

// message definitions follow C rules
// overridden message (not declared, but defined)
- (id) init {
if (self = [super init]) {
level = 10; // set default level
}
}

- (id) initWithName:(NSString *)newName level:(int)newLevel {
[self init];
[self setName:newName];
[self setLevel:newLevel];

return self;
}

- (NSString *)name {
return name;
}

- (int)level {
return level;
}

- (void)setName:(NSString*)newName {
// See blog entry on memory management for retain / release notes.
[newName retain];
[name release];
name = newName;
}

- (void) setLevel:(int)newLevel {
level = newLevel;
}

// This is equivilant to Java's toString method.
- (NSString *)description {
NSString *desc = [NSString stringWithFormat:@"Name=%s level=%d", [name UTF8String], level];
return desc;
}

- (void)dealloc {
[name release];
[super dealloc];
}

@end // marks end of implementation of the class


Using the class above. Write a main.m file:


#import "Geek.h"

int main(int argc, char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

Geek *a = [[Geek alloc] init];
[a setName:@"Jack"];
NSLog(@"Hello. Geek: %@", a);
[a dealloc];

a = [[Geek alloc] initWithName:@"Jill" level:15];
NSLog(@"Hello. Geek: %@", a);
[a dealloc];

[pool release];
return 0;
}


Compiling and running the program:

$ gcc -framework Foundation Geek.m main.m
$ ./a.out
2008-12-15 19:24:47.043 a.out[7052:10b] Hello. Geek: Name=Jack level=10
2008-12-15 19:24:47.045 a.out[7052:10b] Hello. Geek: Name=Jill level=15


There you have it, a pretty useless class, but illustrates basic objective-c usage. Should be useful is getting started with iPhone development.

No comments:

Post a Comment