You are on page 1of 46

Objective-C

Day 1 - Session 1

Vitor Carreira
ESTG/IPL July 24-28, 2012 Leiria, Portugal

Quick Introduction

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

Requirements
Requirements for this session

Moderate knowledge of the C programming language Basic knowledge of Object Oriented Programming concepts (instance vs class, encapsulation, inheritance and polymorphism)

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

Why Objective-C?
Selected as the main language by NeXT
developing Mac OS X (2001) using Objective-C legacy :) (company founded by Steve Jobs) to develop the NeXTStep OS

In 1996, Apple acquires NeXT and starts Objective-C is not a choice but rather a
July 24-28, 2012 iOS Game Development - International Summer School, ESTG/IPL 4

Syntax

Objective-C 2.0 is a superset of the C99 standard. All features of the C language are preserved

Case sensitive, strongly typed, every variable should be declared before used, separates function declaration (header le) from function implementation (implementation le), vars declared inside a function are local, pass by reference using pointers, etc Same set of operators and control ow structures Extensions to the C language are identied with the @ symbol New le extensions: .m (implementation le), .h (header le) Var names: lowerCamelCase Function names: UpperCamelCase
iOS Game Development - International Summer School, ESTG/IPL 5

New features

July 24-28, 2012

Data value types

Value types: char, int, oat, double Modiers: unsigned, short, long By default, are integers are signed Enumerations: keyword enum Structures: keyword struct
July 24-28, 2012 iOS Game Development - International Summer School, ESTG/IPL 6

Pre-processor

All lines that start with # are executed by the pre-processor. Just to recap:

#dene - denes a macro #if, #else, #endif - conditional includes code or macros #import - includes the le only once (should be used instead of #include)
#import <Foundation/Foundation.h> #define PI 3.14159265 int main(int argc, const char * argv[]) { #if DEBUG NSLog(@"Debug mode on"); #endif NSLog(@"Hello, PI (%g)!", PI); return 0; }

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

Hello World
main.m
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { int igdDays = 5; NSLog(@"Hello, iGD - Welcome aboard to %d days of fun!", igdDays); } return 0; }

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

Demo time Lets try it on Xcode

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

Classes

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

10

Classes 1/2
In Objective-C, a class has two parts:

@interface - part where the class interface is declared (public instance/class methods and public properties). The public interface must be placed on an header le (.h) @implementation - part where the methods are implemented. The implementation must be placed on a code le (.m)

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

11

Classes 2/2

Some conventions:

Class name: UpperCamelCase Members and properties: lowerCamelCase

Objective-C doesnt have namespaces. It is recommended to use a prex of 2 to 4 letters to avoid collisions between class names Some prexes are already reserved: NS, IB, CG, etc
iOS Game Development - International Summer School, ESTG/IPL 12

July 24-28, 2012

Syntax

Interface part 1/3

@interface ClassName : ParentClassName { // Optional public or protected ivars } // Public property declaration // Public methods declaration @end

Example (ComplexNumber.h)
@interface ComplexNumber : NSObject - (double)modulus; - (void)setRadius:(double)aRadius phase:(double)aPhase; - (void)debug; @end

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

13

Interface part 2/3



Every class should be a direct or indirect descendant of NSObject Instance variables (ivars) that are protected or public (not recommended) are declared between {} If no scope is given, ivars are @protected. Available scopes: @public, @protected, @private and @package Syntax to declare an instance variable: Type instanceVarName;
iOS Game Development - International Summer School, ESTG/IPL 14

July 24-28, 2012

Interface part 3/3

Method declaration: Method type:

MethodType (ReturnType)namePart1: (Type)param1 namePart2: (Type)param2, ...;

Use the - sign for instance methods Use the + sign for class methods
iOS Game Development - International Summer School, ESTG/IPL 15

July 24-28, 2012

Method overloading
Method overloading is not supported

Methods with the same name but different parameter types

How the name of the method is represented?


// Name = modulus - (double)modulus; // Name = debug - (void)debug; // Name = setRadius:phase: - (void)setRadius:(double)aRadius phase:(double)aPhase; // Name = setRadius: - (void)setRadius:(double)aRadius
July 24-28, 2012 iOS Game Development - International Summer School, ESTG/IPL 16

Implementation part 1/2


Syntax
@implementation ClassName { // Optional private ivars } // Public or private methods implementation @end

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

17

Implementation part 2/2


Example (ComplexNumber.m)
#import ComplexNumber.h @implementation ComplexNumber { double realPart; double imaginaryPart; } - (double)modulus { return sqrt(realPart*realPart + imaginaryPart*imaginaryPart); } - (void)setRadius:(double)aRadius phase:(double)aPhase { realPart = aRadius * cos(aPhase); imaginaryPart = aRadius * sin(aPhase); } - (void)debug { NSLog(@"%g + %gi", realPart, imaginaryPart); } @end

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

18

Putting all together main.m


#import <Foundation/Foundation.h> #import "ComplexNumber.h" int main(int argc, const char * argv[]) { ComplexNumber *c1 = [[ComplexNumber alloc] init]; [c1 debug]; [c1 setRadius:5 phase:M_PI_4]; [c1 debug]; return 0; }

[[ComplexNumber alloc] init] Allocates e initializes a new instance of ComplexNumber An object is always represented by a pointer
July 24-28, 2012 iOS Game Development - International Summer School, ESTG/IPL 19

Method invocation

In Objective-C, invoking a method consists en sending a message to it. General syntax: [receptor message] Instance methods (the instance is the receptor):
[instance methodName] [instance methodName:param1] [instance methodNamePart1:param1 part2:param2]

Class methods: the same syntax but the receptor is the class name (e.g. [ComplexNumber alloc])

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

20

Getters and setters 1/3


By convention:

The getter method name is equal to the ivar.The get prex is not used The setter has the following name:
- (void)set<IVarName>:(IVarType)value
@interface ComplexNumber : NSObject - (double)realPart; // Getter - (void)setRealPart:(double)value; // Setter - (double)imaginaryPart; // Getter - (void)setImaginaryPart:(double)value; // Setter (...) @end
July 24-28, 2012 iOS Game Development - International Summer School, ESTG/IPL 21

Getters and setters 2/3


@implementation ComplexNumber { double realPart; double imaginaryPart; } - (double)realPart { return realPart; } - (void)setRealPart:(double)value { realPart = value; } - (double)imaginaryPart { return imaginaryPart; } - (void)setImaginaryPart:(double)value { imaginaryPart = value; } (...) @end July 24-28, 2012 iOS Game Development - International Summer School, ESTG/IPL 22

Getters and setters 3/3


int main(int argc, const char * argv[]) { Not ComplexNumber *c1 = [[ComplexNumber alloc] init];

cool!

[c1 setRealPart:3]; [c1 setImaginaryPart:2]; double newValue = [c1 realPart] * 3; [c1 setRealPart: newValue]; [c1 setImaginaryPart:[c1 imaginaryPart] * 3]; [c1 debug]; return 0; }

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

23

Properties 1/4

Objective-C 2.0 has introduced a new syntax to implement getters and setters called dot syntax Invoking getters and setters becomes familiar. Some examples:
int age = [person age]; int age = person.age; // getter dot syntax [person setAge: 39]; person.age = 39; // setter dot syntax [[person father] setAge: 68]; person.father.age = 68; // setter dot syntax

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

24

Properties 2/4

Declaring a property:

On the interface part use the @property directive


@property (optional attributes) PropertyType propertyName

@interface ComplexNumber : NSObject @property double realPart; @property double imaginaryPart; - (double)modulus; - (void)setRadius:(double)aRadius phase:(double)aPhase; - (void)debug; @end

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

25

Properties 3/4

Synthesizing a property:

On the implementation part use the @synthesize directive


@synthesize propertyName[=optional_ivarname];

By default, @synthesize follows the same conventions for getters and setters and injects the following pair of methods: -(void)setIVarName:(Type)value; -(Type)varIName;
@implementation ComplexNumber @synthesize realPart; @synthesize imaginaryPart;
(...)

@end

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

26

Properties 4/4
#import "ComplexNumber.h" int main(int argc, const char * argv[]) { ComplexNumber *c1 = [[ComplexNumber alloc] init]; c1.realPart = 3; c1.imaginaryPart = 2; [c1 debug]; c1.realPart *= 3; c1.imaginaryPart += 2; [c1 debug]; return 0; }

Easier to type. Easier to remember

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

27

Inheritance 1/2

Objective-C only supports single inheritance There is no such thing as a protected method To redene a parent method you just have to provide the new implementation (keeping the method signature) The keyword self is a reference for the current instance The keyword super refers to the parent of the current instance
iOS Game Development - International Summer School, ESTG/IPL 28

July 24-28, 2012

Inheritance 2/2

In Objective-C method invocation follows the dynamic binding mechanism. One a message is sent to a receptor:

The runtime checks if the receptor implements the method invoked. If the method is founded it is executed. If the method is not founded, the message is sent to the receptors parent

The receptor hierarchy is traversed until one of the following conditions is veried:

The method is founded and invoked The method is not found when reaching the hierarchy top and an exception is thrown
iOS Game Development - International Summer School, ESTG/IPL 29

July 24-28, 2012

Some Language Considerations

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

30

Exceptions 1/3
Exception handling is similar to C# or Java
@try { [f noSuchMethod]; } @catch (NSException *exception) { NSLog(@Caught %@%@, [exception name], [exception reason]); } @finally { NSLog(@Always called); }

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

31

Exceptions 2/3

You can have multiple @catch blocks to catch different types of exceptions Use @throw to throw an exception

If inside a @catch block the exception instance can be omitted @throw; // Re throws the exception caught

NSException is the base class for all exceptions


The runtime doesnt impose this kind of check

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

32

Exceptions 3/3

In languages like C# or Java, exceptions is fairly commonplace and used intensively to signal errors that affect the execution ow Exceptions are resource-intensive in Objective-C.You should not use exceptions for general ow-control, or simply to signify errors. Instead you should use the return value of a method or function to indicate that an error has occurred, and provide information about the problem in an error object
- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName

Very important

error:(NSError **)outError;

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

33

BOOL vs bool

Objective-C 1.0 didnt have a boolean data type So the type BOOL was introduced to the language with the macros YES (true) and NO (false) Objective-C 2.0 is a superset of C99 so it also has the boolean type bool that is almost never used due the legacy code
BOOL isLessonComplete = NO; bool newButSeldomUsed = true;

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

34

Static vs dynamic typing


Static typing - the data type is always
specied
ComplexNumber *aNumber;

Dynamic typing - the data type is not


id anyObject;

specied. So the variable can represent any object (equivalent to the void * in C)

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

35

Nil instance

The keyword nil represents a null instance. It can be used:

To assign an null object to a variable


aComplexNumber = nil;

As part of a condition
if (aComplexNumber == nil) or if (!aComplexNumber)

As a method argument:
[slider setTarget: nil];

As a receptor (message is ignored and returns 0)


aComplexNumber = nil; value = [aComplexNumber modulus];

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

36

Selectors 1/2

SEL is a data type called selector that represents a method (similar to a function pointer) A selector is declared using the methods full name. The following method
- (void)setRadius:(double)r phase:(double)p

Could be represented with the following selector:


SEL setAll = @selector(setRadius:phase:);

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

37

Selectors 2/2

The NSObject class provides several methods that work with selectors (e.g. respondsToSelector, performSelector, etc). For example:

id receiver = self.target; SEL sel = self.action; if ([receiver respondsToSelector:sel]) { [receiver performSelector:sel withObject:self]; }
July 24-28, 2012 iOS Game Development - International Summer School, ESTG/IPL 38

Allocation and Initialization


There is no such thing as constructors

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

39

Allocation and initialization 1/5


AClass *anObject = [[AClass alloc] init];

Two steps are required to instantiate an class:


1. Allocate memory for the instance. NSObject provides two methods for that: alloc e allocWithZone

When memory is allocated all ivars are set to zero (objects are set to nil)

2. Initialize the instance with the desired values. The class is responsible to provide proper initializers to initialize the instance. By convention (this is very important) all initializers methods must start with init

July 24-28, 2012

All classes that have instance variables should provide at least one initializer

iOS Game Development - International Summer School, ESTG/IPL

40

Allocation and initialization 2/5


-(id)init {...}

An initializer must initialize all ivars of the receptor and returns its own instance Exceptionally a different instance or even nil can be returned by an initializer. So the value returned by the initializer should always be kept By convention, the initializer should be called only once (very important for memory management)
iOS Game Development - International Summer School, ESTG/IPL 41

July 24-28, 2012

Allocation and initialization 2/5


Incorrect
AClass *anObject = [AClass alloc]; [anObject init]; [anObject someMethod];

Correct
AClass *anObject = [AClass alloc]; anObject = [anObject init]; [anObject someMethod];

Typical code
AClass *anObject = [[AClass alloc] init]; [anObject someMethod];

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

42

Allocation and initialization 4/5


Rules to implement an initializer

By convention, the method should start with the name init The method must return id If the class has more than one initializer it is required to state which one is the designated initializer. This is the initializer that all the other initializers should invoke The designated initializer is the only one to invoke the parent initializer You must assign to self the result of calling the designated or parent initializer.You should check if the result is nil (exceptionally an initializer can return nil or an different instance of the one currently allocated) You should not use getters and setters to initialize ivars The initializer must always return self (or nil if an error occurs)
iOS Game Development - International Summer School, ESTG/IPL 43

July 24-28, 2012

Example

Allocation and initialization 5/5

- (id)init { // Calls the designated initializer return [self initWithReal:0 imaginary:0]; } // This is my designated initializer // A general rule of thumb (although not always the case) is that the designated initializer is the initializer with the most parameters. - (id)initWithReal:(double)real imaginary:(double)imaginary { // Calls the parent initializer self = [super init]; if (self) { realPart = real; imaginaryPart = imaginary; } return self; } - (id)initWithRadius:(double)aRadius phase:(double)aPhase { // Calls the designated initializer return [self initWithReal:aRadius * cos(aPhase) imaginary:aRadius * sin(aPhase)]; }

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

44

Some classes combine allocation and


initialization in a single step

Combining allocation and initialization


constructors and usually start with the name of the class

This methods are called convenience Examples from NSString:

+ (id)stringWithCString:(const char *)cString encoding:(NSStringEncoding)enc; + (id)stringWithFormat:(NSString *)format, ...;

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

45

Before moving to the next session. Any questions?

July 24-28, 2012

iOS Game Development - International Summer School, ESTG/IPL

46

You might also like