Crash Course in Objective-C

40
Computer Science Large Practical: Crash Course in Objective-C Stephen Gilmore School of Informatics Friday 12th October, 2012 Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 1 / 33

description

A crash course in Objective-C.

Transcript of Crash Course in Objective-C

Page 1: Crash Course in Objective-C

Computer Science Large Practical:

Crash Course in Objective-C

Stephen Gilmore

School of Informatics

Friday 12th October, 2012

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 1 / 33

Page 2: Crash Course in Objective-C

Acknowledgements

We are following Appendix C of

Beginning iOS 5 ApplicationDevelopment

Wei-Meng Lee

John Wiley & Sons, Inc.

2012

www.it-ebooks.info

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 2 / 33

Page 3: Crash Course in Objective-C

Objective-C sources

Objective-C source code files are contained in two types of files:

.h header files

.m implementation files

Thus a project could contain a file called SomeClass.h

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 3 / 33

Page 4: Crash Course in Objective-C

Directives

If you observe the content of the SomeClass.h file, you will notice that atthe top of the file is typically an #import statement:

#import <Foundation/Foundation.h>

@interface SomeClass : NSObject {

}

@end

The #import statement is known as a preprocessor directive.(NS stands for ”NeXTStep”, the project which created Objective-C.)

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 4 / 33

Page 5: Crash Course in Objective-C

Importing your own header files

To import a header file from within your project, you use the quotecharacters, as in the case of the SomeClass.m file:

#import "SomeClass.h"

@implementation SomeClass

@end

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 5 / 33

Page 6: Crash Course in Objective-C

Classes

To declare a class, you use the @interface compiler directive, like this:

@interface SomeClass : NSObject {

}

This is done in the header file (.h), and the class declaration contains noimplementation. The preceding code declares a class named SomeClass,and this class inherits from the base class named NSObject.

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 6 / 33

Page 7: Crash Course in Objective-C

Classes

To implement a class declared in the header file, you use the@implementation compiler directive, like this:

#import "SomeClass.h"

@implementation SomeClass

@end

This is done in a separate file from the header file. In Objective-C, youdefine your class in an .m file.

Note

Note that the class definition ends with the @end compiler directive.

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 7 / 33

Page 8: Crash Course in Objective-C

Mutual recursion

If your class references another class defined in another file, you needto import the header file of that file before you can use it.

To prevent circular inclusion, Objective-C uses the @class compilerdirective as a forward declaration to inform the compiler that the classyou specified is a valid class.

You usually use the @class compiler directive in the header file; and inthe implementation file, you can use the @import compiler directiveto tell the compiler more about the content of the class you are using.

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 8 / 33

Page 9: Crash Course in Objective-C

Mutual recursion example

// SomeClass.h

#import <Foundation/Foundation.h>

@class AnotherClass; // forward declaration

@interface SomeClass : NSObject {

// an object from AnotherClass

AnotherClass *anotherClass;

}

@end

// AnotherClass.h

#import <Foundation/Foundation.h>

@class SomeClass; // forward declaration

@interface AnotherClass : NSObject {

SomeClass *someClass; // using an instance of SomeClass

}

@end

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 9 / 33

Page 10: Crash Course in Objective-C

Mutual recursion example

// SomeClass.h

#import <Foundation/Foundation.h>

@class AnotherClass; // forward declaration

@interface SomeClass : NSObject {

// an object from AnotherClass

AnotherClass *anotherClass;

}

@end

// AnotherClass.h

#import <Foundation/Foundation.h>

@class SomeClass; // forward declaration

@interface AnotherClass : NSObject {

SomeClass *someClass; // using an instance of SomeClass

}

@end

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 9 / 33

Page 11: Crash Course in Objective-C

Class instantiation

To create an instance of a class, you typically use the alloc keyword toallocate memory for the object and then return it to a variable of the classtype:

SomeClass *someClass = [SomeClass alloc];

In Objective-C, you need to prefix an object name with the * characterwhen you declare an object.

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 10 / 33

Page 12: Crash Course in Objective-C

Primitive types

If you are declaring a variable of primitive type (such as float, int, CGRect,NSInteger, and so on), the * character is not required. Here are someexamples:

CGRect frame; // CGRect is a structure

int number; // int is a primitive type

NSString *str; // NSString is a class

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 11 / 33

Page 13: Crash Course in Objective-C

The id type

Besides specifying the returning class type, you can also use the id type,like this:

id someClass = [SomeClass alloc];

id str;

The id type means that the variable can refer to any type of object; hence,the * is implied.

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 12 / 33

Page 14: Crash Course in Objective-C

Fields

Fields are the data members of objects. For example, the following codeshows that SomeClass has three fields — anotherClass, rate, and name:

// SomeClass.h

#import <Foundation/Foundation.h>

@class AnotherClass; // forward declaration

@interface SomeClass : NSObject {

// an object from AnotherClass

AnotherClass *anotherClass;

float rate;

NSString *name;

}

@end

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 13 / 33

Page 15: Crash Course in Objective-C

Access Privileges

By default, the access privilege of all fields is @protected. However, theaccess privilege can also be @public or @private. The following listdescribes the various access privileges:

@private Visible only to the class that declares it

@public Visible to all classes

@protected Visible to the class that declares it and inheriting classes

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 14 / 33

Page 16: Crash Course in Objective-C

Public fields

To make the rate and name visible outside the class, modify theSomeClass.h file by adding the @public compiler directive:

#import <Foundation/Foundation.h>

@class AnotherClass; // forward declaration

@interface SomeClass : NSObject {

AnotherClass *anotherClass;

@public

float rate;

@public

NSString *name;

}

@end

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 15 / 33

Page 17: Crash Course in Objective-C

Public fields

We can now access the fields ”rate” and ”name” directly (using the ”->”operator).

SomeClass *someClass = [SomeClass alloc];

someClass->rate = 5; // rate is declared public

someClass->name = @"Wei-Meng Lee"; // name is public

Although we can access the fields directly, doing so goes against thedesign principles of object-oriented programming’s rule of encapsulation.

A better way is to encapsulate the two fields we want to expose inproperties, as we will see later.

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 16 / 33

Page 18: Crash Course in Objective-C

Methods

Objective-C supports two types of methods: instance methods and classmethods.

Instance methods can only be called using an instance of the class;and they are prefixed with the minus sign (−) character.

Class methods can be invoked directly using the class name and donot need an instance of the class in order to work. Class methods areprefixed with the plus sign (+) character.

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 17 / 33

Page 19: Crash Course in Objective-C

Methods in interfaces

@interface SomeClass : NSObject {

AnotherClass *anotherClass;

float rate;

NSString *name;

}

// instance methods

-(void) doSomething;

-(void) doSomething:(NSString *) str;

-(void) doSomething:(NSString *) str withAnotherPara:(float)

value;

// class method

+(void) alsoDoSomething;

@end

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 18 / 33

Page 20: Crash Course in Objective-C

Methods in implementations (1/2)

#import "SomeClass.h"

@implementation SomeClass

// instance methods

-(void) doSomething {

// implementation here

}

-(void) doSomething:(NSString *) str {

// implementation here

}

-(void) doSomething:(NSString *) str withAnotherPara:(float)

value {

// implementation here

}

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 19 / 33

Page 21: Crash Course in Objective-C

Methods in implementations (2/2)

// class method

+(void) alsoDoSomething {

// implementation here

}

@end

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 20 / 33

Page 22: Crash Course in Objective-C

Invoking methods

To invoke the three instance methods, you first need to create an instanceof the class and then call them using the instance created:

SomeClass *someClass = [SomeClass alloc];

[someClass doSomething];

[someClass doSomething:@"some text"];

[someClass doSomething:@"some text" withAnotherPara:9.0f];

Class methods can be called directly using the class name, as the followingshows:

[SomeClass alsoDoSomething];

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 21 / 33

Page 23: Crash Course in Objective-C

Message Sending (Calling Methods)

Strictly speaking, in Objective-C you do not call a method; rather,you send a message to an object.

The message to be passed to an object is resolved during runtime andis not enforced at compile time.

This is why the compiler does not stop you from running yourprogram even though you may have misspelled the method name.

It does warn you that the target object may not respond to yourmessage, though, because the target object will simply ignore themessage (and in most situations result in a runtime exception).

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 22 / 33

Page 24: Crash Course in Objective-C

Message Sending (Calling Methods)

Strictly speaking, in Objective-C you do not call a method; rather,you send a message to an object.

The message to be passed to an object is resolved during runtime andis not enforced at compile time.

This is why the compiler does not stop you from running yourprogram even though you may have misspelled the method name.

It does warn you that the target object may not respond to yourmessage, though, because the target object will simply ignore themessage (and in most situations result in a runtime exception).

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 22 / 33

Page 25: Crash Course in Objective-C

Nested method calls

Method calls can also be nested, as the following example shows:

NSString *str =

[[NSString alloc] initWithString:@"Hello World"];

Here, you first call the alloc class method of the NSString class and thencall the initWithString: method of the returning result from the allocmethod, which is of type id, a generic C type that Objective-C uses for anarbitrary object.

Note

In general, you should not nest more than three levels because anythingmore than that makes the code difficult to read.

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 23 / 33

Page 26: Crash Course in Objective-C

Defining properties

Properties enable you to expose the fields in your class so that youcan control how values are set or returned.

In the earlier example we saw that we can directly access the fields ofa class using the ”->” operator.

However, this is not the ideal way; ideally, you should expose yourfields as properties in the interface.

// expose the rate field

-(float) rate; // get the value of rate

-(void) setRate:(float) value; // set the value of rate

// expose the name field

-(NSString *) name; // get the value of name

-(void) setName:(NSString *) value; //set the value of name

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 24 / 33

Page 27: Crash Course in Objective-C

Getting and setting properties

To set the value of these properties, you need to call the methods prefixedwith the set keyword:

SomeClass *sc = [[SomeClass alloc] init];

[sc setRate:5.0f];

[sc setName:@"Wei-Meng Lee"];

To obtain the values of properties, you can either call the methods.

NSLog([sc name]); // call the method

To make a property read-only, simply remove the method prefixed with theset keyword.

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 25 / 33

Page 28: Crash Course in Objective-C

Initializers

When you create an instance of a class, you often initialize it at the sametime.

SomeClass *sc = [[SomeClass alloc] init];

The alloc keyword allocates memory for the object; and when an object isreturned, the init method is called on the object to initialize the object.The init method is defined in the NSObject class, which is the base classof most classes in Objective-C.

Convention

If you want to create additional initializers, you can define methods thatbegin with the init word (use of the init prefix is more of a norm than ahard-and-fast rule).

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 26 / 33

Page 29: Crash Course in Objective-C

Memory management

Like most other popular languages, Objective-C supports garbagecollection, which removes unused objects when they go out of scopeand hence releases memory that can be reused.

However, because of the severe overhead involved in garbagecollection, iOS does not support garbage collection.

This leaves the developer to manually allocate and de-allocate thememory of objects when they are no longer needed.

Note

In the CSLP we are not targeting iOS, but still it seems worthwhile tolearn a little about reference counting. Recent versions of Mac OS X andiOS include automatic reference counting, making memory managementthe same on Mac OS X and iOS.

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 27 / 33

Page 30: Crash Course in Objective-C

Reference Counting

To help you allocate and de-allocate memory for objects, iOS uses ascheme known as reference counting to keep track of objects todetermine whether they are still needed or can be disposed of.

Reference counting basically uses a counter for each object; and aseach object is created, the count increases by 1.

When an object is released, the count decreases by 1.

When the count reaches 0, the memory associated with the object isreclaimed by the OS.

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 28 / 33

Page 31: Crash Course in Objective-C

Reference counting example

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 29 / 33

Page 32: Crash Course in Objective-C

Reference counting example

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 29 / 33

Page 33: Crash Course in Objective-C

Reference counting example

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 29 / 33

Page 34: Crash Course in Objective-C

Reference counting example

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 29 / 33

Page 35: Crash Course in Objective-C

Reference counting example

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 29 / 33

Page 36: Crash Course in Objective-C

Reference counting example

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 29 / 33

Page 37: Crash Course in Objective-C

alloc

The alloc keyword allocates memory for an object that you are creating.An example is as follows:

NSString *str = [[NSString alloc] initWithString:@"Hello"];

Here, you are creating an NSString object and instantiating it with adefault string.

When the object is created, the reference count of that object is 1.

Because you are the one creating it, the object belongs to you, and it isyour responsibility to release the memory when you are done with it.

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 30 / 33

Page 38: Crash Course in Objective-C

new

Besides using the alloc keyword to allocate memory for an object, you canalso use the new keyword, like this:

NSString *str = [NSString new];

The new keyword is functionally equivalent to

NSString *str = [[NSString alloc] init];

As with the alloc keyword, using the new keyword makes you the owner ofthe object, so you need to release it when you are done with it.

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 31 / 33

Page 39: Crash Course in Objective-C

retain

The retain keyword increases the reference count of an object by 1.Consider the following example:

NSString *str = [[NSString alloc] initWithString:@"Hello"];

NSString *str2 = str;

Here, you do not own str2 because you do not use the alloc keyword onthe object. When str is released, the str2 pointer will no longer be valid.To ensure that str2 is available even if str is released, you need to use theretain keyword:

NSString *str = [[NSString alloc] initWithString:@"Hello"];

NSString *str2 = str;

[str2 retain]; // str2 now also "owns" the object

[str release]; // str can now be released safely

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 32 / 33

Page 40: Crash Course in Objective-C

release

When you are done with an object, you need to manually release it byusing the release keyword:

NSString *str = [[NSString alloc] initWithString:@"Hello"];

//...do what you want with the object...

[str release];

When you use the release keyword on an object, it causes the referencecount of that object to decrease by 1.

When the reference count reaches 0, the memory used by the object isreleased.

Stephen Gilmore (School of Informatics) Computer Science Large Practical Friday 12th October, 2012 33 / 33