Tuesday 8 January 2013

An introduction to Objective-C


Objective-C is the main language used by iOS. It is, contrary to C++, a superset of C. This means that an Objective-C compiler can also compile code written in C, and an Objective-C class can include C code without a problem.
Here follows a short explanation of  Object-oriented programming and an introduction to Objective-C’s syntax. It is by no means complete and all-encompassing, but it will hopefully give the reader enough knowledge to understand our paper and the basics of Objective-C.

Object-oriented programming

         Object-oriented programming (OOP) is a programming paradigm in which a concept is represented by an ‘object’. An object has functions associated with it, called methods. Contrary to list-like conventional programs, an object-orientated program can be seen as a collection of machines working with each other, and corresponding with each other. Objects can all send and receive information.
         In short, objects can be defined as data, combined with methods that ensure the data is used in the appropriate matter for that data (see the example in Syntax).
         In OOP, a programmer often places data in such a way that only the object associated with that data can access it. Messages are used to pass this data on and let other objects access it. Although officially one does not simply call a method but instead sends a message in Objective-C, in programming-practice they are nearly identical. Methods can be seen as the letters objects use to communicate with each other. This has the great advantage that when there is a bug in a certain function, the bug can only affect the data accessible by that object, hence limiting its effects.

Classes, pointers and instances

         A class is the definition of an object. It consists of two files: the header file (usually named className.h), where the interface is defined, and the implementation file (className.m), where the methods are defined.
         Classes can be subclassed from other classes, thus creating a program hierarchy. A subclass can use its parentclass’ methods. Subclassing can be used (amongst other things like categories) to give structure to a program, and organize code. As bigger projects tend to get unorganized, it’s important to plan the structuration of the program ahead of coding.
         A class can be instantiated. Let’s say we’ve got a class named CarObjectClass. We want to make an object that functions like a car. In order to make an instance of carObjectClass, we type the following:
CarObjectClass* ferrari = [[CarObjectClass alloc] init];


We have now created a pointer with the name ferrari. This pointer does, quite literally, point to an object that is an instance of the CarObjectClass. This means that it is not the actual object itself; it just points to the location of an object. The alloc method (to put it briefly) handles the memory for the creation of the object. The init method is called upon creation and allows for the programmer to set the object upon creation. In our car example, the method startEngine could for instance be called. The init method is often written in such a way that it returns self to the caller –in other words, the object itself is the output of the method, thus assigning it to the pointer ferrari.
        
Syntax

General
         The following symbols and statements are not necessarily Objective-C syntax, but are, however, crucial to understanding the code in this paper. Please consider the following:
//Text with "//" in front of it is a comment.
   //A line of code always ends with a semicolon.
    
    int i=1; //defines a variable of type integer i and gives it a value of 1;
    
    
    //If statement:

    if(i==1){                   //"==" means “is equal to”
       //do something
     }
     else if(i!=2){              //"!=" means “is not equal to”
       //do something else
    }


 if(i<8&&i>3){   //"&&" means "and"
      //do something
 }


 if(i==5||i==1){ //"||" means "or"
      //do something
 }
    
    
 //while statement
 //while i is smaller than or equal to 3, do something;

    while(i<=3){            
        //do something
    }
    
 //for statement
 //starting at 0, check if p is smaller than 9, if so, do something, then add 1 to p, and repeat;

for(int p=0; p<9; p++)
//do something

NSArray* carArray= [[NSArray alloc]initWithObjects:ferrari,mercedes, nil];
//create an array and add objects ferrari and mercedes.

//for-in statement
//for every object in carArray, make a pointer called car that points towards that object of the CarObjectClass;

for(CarObjectClass*car in carArray){
//do something with variable car
}
Interface
         The interface of a class (in the header file) takes the following form:
#import "usedClass.h"
@interface classname : superclassname {
 // instance variables
} 

+ classMethod1;
+ (return_type)classMethod2;
+ (return_type)classMethod3:(prm1_type)prm1_varName;
 
- (return_type)instanceMethod1:(prm1_type)prm1_varName:(prm2_type)prm2_varName;
- (return_type)instanceMethod2WithParameter:(prm1_type)prm1_varName otherParameter:(param2_type)param2_varName;

@end
The methods with plus sings are class methods: methods that can only be called on the class itself, not on an instance. They have no access to instance variables. The minus signs mark instance methods, which can only be called on a particular instance.
         If we look at the interface of our car example, we see the following:
#import "cocos2d.h"
#import "wheelClass.h"


@interface CarObjectClass : CCSprite
{

 wheelClass*wheels; 
 int speed;
 float direction;
 BOOL speedingUp;

}

+(CCSprite *) sprite;
-(void)speedUpTo:(int)targetSpeed // denotes instance method with return type void, meaning that nothing is returned by this method. Return types can be any standard C type, pointers to a generic or a specific type of object (such as NSArray* or NSString*). The default return type is the generic Objective-C type id.

@property float speed; // here we make the instance variable a property. This means that the variable can be accessed (read, write or both) by other instances. For instance, an update method in another class could have the line ferrari.speed=10;. This way, instance variables can be changed without having to call a separate method.


@end
Implementation
         The actual code for the methods is written in the implementation (the .m file). A general implementation looks like this:
@implementation classname
+ (return_type)classMethod
{
 // implementation
}
- (return_type)instanceMethod
{
 // implementation
}
@end
To once again take this to our car example:
@implementation CarObjectClass
@synthesize speed;  //here we synthesize the speed property

+ (CCSprite*)sprite
{
//create a sprite
    CCSprite*sprite=[CCSprite spriteWithFile:@"SpriteImage.png"];
//return it
    return sprite;
}

//the init method is not defined in the header file, as this is a standard method, part of the NSObject superclass.
-(id)init{
if(self=[super init]){

[self speedUpTo:142];    //methods needed for setup are called here

}
return self;      //the instance is returned

}

//the argument passed to this method has been named targetSpeed inside the method: the Objective-C syntax allows the pseudo-naming of arguments.

-(void)speedUpTo:(int)targetSpeed 
{

 if (!speedingUp) {

        speed=targetspeed/2;   
        speedingUp=YES;

       }

}
@end

                                 
Sending a message    
         In order to send a message to an object, the following notation is used:
[objectPointer doMethod:argument];
The object that objectPointer is pointing to will now execute the function doMethod, with an argument. If we extend this to our car example , it would look like this:
[ferrari speedUpTo:250];

Ferrari will now call the method speedUpTo and speed up to 250 km/h (it’s a Ferrari, after all!).

No comments:

Post a Comment