Hello World in Objective C and Compiling with GCC

Contents

Overview

There are a lot of articles in Introduction of Objective-C and explaining basic concepts. But this article attempts to explain the basics of Objective-C without the influence of any framework  i.e without the influence of the GNUStep or NextStep or Cocoa framekwork. So, I  have used the primitive types and the basic object from Objective-C base framework and complied with GCC compiler. Also I did not want to use Apple’s XCode editor to write an objective-c program, instead I used Emacs and Terminal to write, build and run the code. After all it s again a C-programming language. This makes the language learning more fun. So this article goes little in-depth to explain the semantics of each element in the Objective-C. If you need a jump start in learning the language you can refer to the Google’s style guide to get an overview about the language. Also try reading the FAQs about the language and you will get more insights.

So, before start learning this here are my two cents:

  1. Think Objects & Intefaces. Though you write the program in a C like language, do not think procedurally.
  2. You might want to write comparitively more number of lines than you think.
  3. Have patience in using brackets.
  4. You might have to learn few other object-oriented mechanism and implementation other than Inheritance, Polymorphism etc.,

Hello World - Object Version

Here is the hello world progarm.

#import <objc/Object.h>

#import <stdio.h>
/** Write your Interface extending Object **/

@implementation HelloWorld:Object
-(void) hello
{
    printf("Hello World");
}
@end

/** Main program for the program execution entry **/
int main(int argv, char* argc[])
{

/* Create an object */
    id o = [HelloWorld new];

/* Pass the message 'hello' to object in the reference variable 'o' */
    [o hello];
}

You should notice the below things in the above program

  1. HelloWorld is extending Object class, which provides the basic features for objects like new, free, alloc etc.,
  2. Used #import instead of the regular #include. The advantage in using #import is, the compiler will make sure that it includes the header file only once during compilation irrespective of how many modules is importing ( i.e including ) the same header file repeatedly. So you can avoid boiler-plate code like this.
#ifndef _INC_HEADER1

#define _INC_HEADER1
#include "header1.h"

#endif

3.The method definition of hello is quite understandable. I’m not going to explain much of it now here. The object created from this class is capable of receiving the message named hello and invoke the method hello defined in the class HelloWorld.

Compile

To compile this program in your terminal either in Linux / Mac use this command.

% gcc -arch i386 -o hello -l objc helloworld.m

gcc is the GNU compiler suite, which you will get by default in your mac / linux machines or you can download it.

-o is to mention that you create an executable with name hello

-lobjc is to make the compiler aware that you are trying to compile & link Object-C language.

helloworld.m is the file which contains the objective-c program.

Output

Hello World

HelloWorld - with Interfaces

Lets add some some salt to it. An another version of the same program can be written like this.

#import <objc/Object.h>

#import <stdio.h>

@interface HelloWorld:Object
{
}
-(void) hello;
@end

@implementation HelloWorld
-(void) hello
{
    printf("Hello World");
}

@end

int main(int argv, char* argc[])
{
    id o = [HelloWorld new];

    [o hello];
}

You will note two differences in this version of the program.

  1. There is an interface class extending Object class
  2. The implementation class doesn't inherit the class Object

Now, you have to play by rules, the rules of the ObjC compiler.

  1. You should name your @interface as same as the @implementation class and you should not inherit any other object for the @implementation class.
  2. Every @interface you write, should extend the Object class, so that you will be able to use the messages (or method) like new, alloc,free etc.,

In above program, after declaring the interface you do not link the interface to the HelloWorld class, but the ObjC compiler will look for that any interface with the same name as the implementation class.

If you do not provide an interface class name, the compiler will throw out this error.

helloworld.m:13: warning: cannot find interface declaration for 'HelloWorld'

Hello World - Modularized

Adding more spice to the program. The third variation to the program is below. I create three different files to split and hold the logical group of code into it’s individual file, i.e basically modularizing the code. You should be known of the advantages of modularizing the code. So, in here I create the below files

  1. HelloWorld.h - Has the interface definition
  2. HelloWorld.m - Has the implementation details
  3. main.m - Has code to instantiate and execute the objects

HelloWorld.h

#import <objc/Object.h>

#import <stdio.h>
@interface HelloWorld:Object
{
-(void) hello;
}

HelloWorld.m

#import "helloworld.h"
@implementation HelloWorld
-(void) hello
{
    printf("Hello World");
}

@end

main.m

#import <objc/Object.h>

#import "helloworld.m"
int main(int argv, char* argc[])
{
    id o = [HelloWorld new];
[o hello];

}

This version of the program is what you will be writing in Realtime. Now let us try to understand the parts of the Objective-C language.

Compile

Since you have two module ( ending with .m ) to compile you might need to mention both of them, so that the gcc compiles all the required modules and then links them to create the executable.

gcc -lobjc -arch i386 -o main main.m helloworld.m

If you have more objective-c implementation files i.e .m files, then you can save the time and pain by including all the files with just using *.m

gcc -lobjc -arch i386 -o main *.m

Understanding the program

Let us spend some time to understand the paradigm of the Objective-C program. The objective-c language, which has a strong influence of SmallTalk based “message” passing mechanism and interface-based-programming, makes you think and write the programs in terms of messages and interfaces.

If you look at the above program, you would notice a pattern which is pretty much as same as a C++ program, except the interfaces and the naming conventions used. Basically the program is of 3 sections:

  1. Headers - Common for any programming language ( C, C++,Java etc., )
  2. Interface & Implementation Classes
  3. And a main program - which runs the code.

Note: If you wanted to write a procedural program, then you don’t have to write a ObjC program

And if you are not familiar with the interface based program and if ObjC is going to be the 1st programming language learning interface-based programming, then I strongly recommend to gain some basic knowledge of what does interfaces means and how they are used and useful to the software construction.

Write your interfaces

Every class you wanted to create i.e the real concrete class which does some logic, you ought to tell the objective-c compiler, something about the class.Thats why you create @interface. @interface create a template of how your object is going to look like, what data it can hold and what messages it can receive to process ( also can receive messages that it cannot support, but you can handle it accordingly) and then you write the @implementation class to say what does you object is going to do. So, it is two piece of work you have to do.

And remember that, when you are modelling your classes, it always becomes your @interface class not @implementation class.

The interface should extend a class which is of type Object or it should be from the family of the type Object to provide the basic operations like new, free, alloc etc., Again Object is an both interface and has an implementation, i.e type Object is a concrete class that you can use as below

id o = [Object new];
@interface HelloWorld:Object
{
    /* data */
}

/* messages */
    -(void) hello;
@end

Write your implementation

The implementation class is going to hold the logic what needs to be performed when a defined message by interface is sent to the object. In this case when a hello message is sent to the object, the implementation defines what needs to be done. Interface class starts with @interface <ClassName> and ends with @end.

@implementation HelloWorld
-(void) hello
{
   ....
   ....
   ....
}

@end