Having picked up an iMac this past Christmas, I've been eager to dive into the opposing world of Mac development. I spend the majority of my time in the workplace developing using C# with the .NET framework.
I spent some time first poking around the net, looking for the best free integrated development environments (IDE) I could find for the Mac OS X Leopard platform. Before you say it, yes yes, there's always vi(m), emacs, pico, etc. While I am a fairly large proponent of vim, I was still curious what else was out there. I took a look around the XCode IDE and was thoroughly impressed with the apparent plethora of project types that could be crafted, however I soon realized I needed to resort to simpler editors first if I really wanted to "understand" some of the new languages and frameworks before letting an IDE do all the mysterious work for me behind the scenes. After digging around further I came across Smultron. Great little light-weight app that suits my needs just perfectly for coding.
For those coming from the .NET arena, wanting to sample the goods on this side of the fence, let me present you with my little analogy that helped me keep things straight. C# is to .NET as Objective-C is to Cocoa. We are dealing with languages and frameworks containing lots of useful libraries.
While this example isn't completely original, I have made sufficient enough changes and additions to warrant considering this equally informative to that of other beginner examples of the language and framework. I make no claims to be an expert with Objective-C nor the Cocoa framework, so there may be more efficient ways to perform certain tasks.
We're going to deal with a simple "Fractions" example from your most basic element of math. Say we wanted to craft our very own Fraction object.
Fraction.h
#import <Foundation/NSObject.h>
@interface Fraction: NSObject
{
int numerator;
int denominator;
}
-(void) print;
-(void) set_Numerator: (int) n Denominator: (int) d;
-(int) get_Numerator;
-(int) get_Denominator;
@end
Fraction.m
#import <stdio.h>
#import "Fraction.h"
@implementation Fraction
// ------------------------------------------------------
-(void) print
{
printf("%i/%i%c", numerator, denominator, '\n');
}
// ------------------------------------------------------
-(void) set_Numerator: (int) n Denominator: (int) d
{
numerator = n;
denominator = d;
}
// ------------------------------------------------------
-(int) get_Denominator
{
return denominator;
}
// ------------------------------------------------------
-(int) get_Numerator
{
return numerator;
}
// ------------------------------------------------------
@end
main.m
#import <stdio.h>
#import "Fraction.h"
int main(int argc, const char *argv[])
{
// Allocate and initialize a Fraction object for use
Fraction *fraction1 = [[Fraction alloc] init];
// Call our set_Numerator:Denominator function, passing both parameters
[fraction1 set_Numerator:3 Denominator:4];
// Display our results
printf("Our Numerator: %i%c", [fraction1 get_Numerator], '\n');
printf("Our Denominator: %i%c", [fraction1 get_Denominator], '\n');
printf("Our Complete Fraction: ");
[fraction1 print];
// Release all of our claimed memory
[fraction1 release];
}
The first thing to point out here is that the implementation files for Objective-C end in ".m" rather than ".c", as you might expect. With that being said, if you have a background in C/C++, this basic structure will look very familiar - a header file depicting the API interface, an implementation file depicting the actual code for each method/function for that class, and a main driver file for controlling the flow of our program.
An additional difference I immediately noticed with the language was the numerous instances of "[..]" notation. This is basically the way method/function calls are made in Objective-C, however they are referred to more as "sending messages". You'll notice I provided a couple different examples above, some calling functions without passing any parameters (print) and other calls passing multiple parameters (set_Numerator:Denominator).
You may be asking yourself about now, okay great, I have the complete source to get me started on a simple example, but since you didn't use XCode, how on earth do I compile this thing? Is it just like C/C++? My answer, pretty darn close! After some trial and error, here's the magic command I use for compiling:
gcc -x objective-c -framework Foundation -lobjc main.m Fraction.m
If all goes well, you should see output precisely like this (including the line to execute the program):
$ ./a.out
Our Numerator: 3
Our Denominator: 4
Our Complete Fraction: 3/4
I plan on creating a gradually more complex series of examples over time, so stay tuned!