iOS Programming: The Big Nerd Ranch Guide, 3/e (Big Nerd Ranch Guides) (9 page)

Read iOS Programming: The Big Nerd Ranch Guide, 3/e (Big Nerd Ranch Guides) Online

Authors: Aaron Hillegass,Joe Conway

Tags: #COM051370, #Big Nerd Ranch Guides, #iPhone / iPad Programming

BOOK: iOS Programming: The Big Nerd Ranch Guide, 3/e (Big Nerd Ranch Guides)
4.07Mb size Format: txt, pdf, ePub
2
Objective-C

iOS applications are written in the Objective-C language using the Cocoa Touch library. Objective-C is a simple extension of the C language, and Cocoa Touch is a collection of Objective-C classes. This book assumes you know some C and understand the ideas of object-oriented programming. If C or object-oriented programming makes you feel uneasy, we recommend starting with
Objective-C Programming: The Big Nerd Ranch Guide
.

 

In this chapter, you will learn the basics of Objective-C and create an application called
RandomPossessions
. Even if you are familiar with Objective-C, you should still go through this chapter to create the
BNRItem
class that you will use later in this book.

 
Objects

Let’s say you need a way to represent a party. Your party has a few attributes that are unique to it, like a name, a date, and a list of invitees. You can also ask the party to do things, like send an email reminder to all the invitees, print name tags, or cancel the party altogether.

 

In C, you would define a
structure
to hold the data that describes a party. The structure would have data members – one for each of the party’s attributes. Each data member would have a name and a type.

 

To create an individual party, you would use the function
malloc
to allocate a chunk of memory large enough to hold the structure. You would write C functions to set the value of its attributes and have it perform actions.

 

In Objective-C, instead of using a structure to represent a party, you use a
class
. A class is like a cookie-cutter that produces objects. The
Party
class creates objects, and these objects are instances of the
Party
class. Each instance of the
Party
class can hold the data for a single party (
Figure 2.1
).

 

Figure 2.1  A class and its instances

 

An instance of
Party
, like all objects, is a chunk of data stored in memory, and it stores the values for its attributes in
instance variables
. So an instance of
Party
might have the instance variables
name
,
date
, and
budget
.

 

A C structure is a chunk of memory, and an object is a chunk of memory. A C structure has data members, each with a name and a type. Similarly, an object has instance variables, each with a name and a type.

 

But there is an important difference between a structure in C and a class in Objective-C: a class has
methods
. A method is similar to a function: it has a name, a return type, and a list of parameters that it expects. A method also has access to an object’s instance variables. If you want an object to run the code in one of its methods, you send that object a
message
.

 
Using Instances

In order to use an instance of a class (an object), you must have a variable that points to the object. A pointer variable stores the location of an object in memory, not the object itself. (It

points to

the object.) A variable that points to an object is declared like so:

 
Party *partyInstance;

This variable is named
partyInstance
. It is meant to be a pointer to an instance of the class
Party
. However, this does not create a
Party
instance – only a variable that can point to a
Party
object.

 
Creating objects

An object has a life span: it is created, sent messages, and then destroyed when it is no longer needed.

 

To create an object, you send an
alloc
message to a class. In response, the class creates an object in memory and gives you a pointer to it, and then you store that pointer in a variable:

 
Party *partyInstance = [Party alloc];

Here an instance of type
Party
is created, and you are returned a pointer to it in the variable
partyInstance
. When you have a pointer to an instance, you can send messages to it. The first message you
always
send to a newly allocated instance is an initialization message. Although sending an
alloc
message to a class creates an instance, the instance isn’t valid until it has been initialized.

 
[partyInstance init];

Because an object must be allocated
and
initialized before it can be used, we always combine these two messages in one line.

 
Party *partyInstance = [[Party alloc] init];
 

The code to the right of the assignment operator (
=
) says,

Create an instance of
Party
and send it the message
init
.

Both
alloc
and
init
return a pointer to the newly created object so that you have a reference to it.

 

Combining two messages in a single line of code is called a
nested message send
. The innermost brackets are evaluated first, so the message
alloc
is sent to the class
Party
first. This returns a new, uninitialized instance of
Party
that is then sent the message
init
.

 
Sending messages

What do you do with an instance that has been initialized? You send it more messages.

 

Let’s take a closer look at message anatomy. First of all, a message is always contained in square brackets. Within a pair of square brackets, a message has three parts:

 

receiver

a pointer to the object being asked to execute a method

 
 

selector

the name of the method to be executed

 
 

arguments

the values to be supplied as the parameters to the method

 
 
 

A party might have a list of attendees that you can add to by sending the party the message
addAttendee:
.

 
[partyInstance addAttendee:somePerson];

Sending the
addAttendee:
message to
partyInstance
(the receiver) triggers the
addAttendee:
method (named by the selector) and passes in
somePerson
(an argument).

 

The
addAttendee:
message has only one argument, but Objective-C methods can take a number of arguments or none at all. The message
init
, for instance, has no arguments.

 

An attendee to a party might RSVP with an edible item. Thus, a party may have another method named
addAttendee:withDish:
. This message takes two arguments: the attendee and the dish the attendee plans to bring. Each argument is paired with a label in the selector, and each label ends with a colon. The selector is all of the labels taken together (
Figure 2.2
).

 

Figure 2.2  Parts of a message send

 

This pairing of labels and arguments is an important feature of Objective-C. In other languages, this method would look like this:

 
partyInstance.addAttendeeWithDish(somePerson, deviledEggs);
 

In these languages, it isn’t completely obvious what each of the arguments sent to this function are. In Objective-C, however, each argument is paired with the appropriate label.

 
[partyInstance addAttendee:somePerson withDish:deviledEggs];
 

It takes some getting used to, but eventually, Objective-C programmers appreciate the clarity of arguments being interposed into the selector. The trick is to remember that for every pair of square brackets, there is only one message being sent. Even though
addAttendee:withDish:
has two labels, it is still only one message, and sending that message results in only one method being executed.

 

In Objective-C, the name of a method is what makes it unique. Therefore, a class cannot have two methods with the same name. However, two methods can have the same individual label, as long as the name of each method differs when taken as a whole. For example, our
Party
class has two methods,
addAttendee:
and
addAttendee:withDish:
. These are two distinct methods and do not share any code.

 

Also, notice the distinction being made between a
message
and a
method
: a method is a chunk of code that can be executed, and a message is the act of asking a class or object to execute a method. The name of a message always matches the name of the method to be executed.

 
Destroying objects

To destroy an object, you set the variable that points at it to
nil
.

 
partyInstance = nil;
 

This line of code destroys the object pointed to by the
partyInstance
variable and sets the value of the
partyInstance
variable to
nil
. (It’s actually a bit more complicated than that, and you’ll learn about the details of memory management in the next chapter.)

 

The value
nil
is the zero pointer. (C programmers know it as
NULL
. Java programmers know it as
null
.) A pointer that has a value of
nil
is typically used to represent the absence of an object. For example, a party could have a venue. While the organizer of the party is still determining where to host the party,
venue
would point to
nil
. This allows us to do things like so:

 
if (venue == nil) {
    [organizer remindToFindVenueForParty];
}

Objective-C programmers typically use the shorthand form of determining if a pointer is
nil
:

 
if (!venue) {
    [organizer remindToFindVenueForParty];
}

Since the
!
operator means

not,

this reads as

if there is not a venue

and will evaluate to true if
venue
is
nil
.

 

If you send a message to a variable that is
nil
, nothing happens. In other languages, sending a message to the zero pointer is illegal, so you see this sort of thing a lot:

 
// Is venue non-nil?
if (venue) {
    [venue sendConfirmation];
}
 

In Objective-C, this check is unnecessary because a message sent to
nil
is ignored. Therefore, you can simply send a message without a
nil
-check:

 
[venue sendConfirmation];

If the venue hasn’t been chosen yet, you won’t send a confirmation anywhere. (A corollary: if your program isn’t doing anything when you think it should be doing something, an unexpected
nil
pointer is often the culprit.)

 

Other books

The Namesake by Jhumpa Lahiri
Wanderlust by Roni Loren
The Battle of Blenheim by Hilaire Belloc
The Midnight Carnival by Erika McGann
Drowning Lessons by Peter Selgin
Mrs. John Doe by Tom Savage
Hollywood Punch by Brenda Janowitz
Anne Barbour by Kateand the Soldier