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
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.
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
.
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:
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.
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:
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.
Because an object must be allocated
and
initialized before it can be used, we always combine these two messages in one line.
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
.
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:
.
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:
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.
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.
To destroy an object, you set the variable that points at it to
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:
Objective-C programmers typically use the shorthand form of determining if a pointer is
nil
:
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:
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:
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.)