iOS Programming: The Big Nerd Ranch Guide, 3/e (Big Nerd Ranch Guides) (15 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)
5.89Mb size Format: txt, pdf, ePub
For the More Curious: Class Names

In simple applications like
RandomPossessions
, we only use a handful of classes. However, as applications grow larger and more complex, the number of classes grows. At some point, you will run into a situation where you have two classes that could easily be named the same thing. This is bad news. If two classes have the same name, it is impossible for your program to figure out which one it should use. This is known as a
namespace collision
.

 

Other languages solve this problem by declaring classes inside a
namespace
. You can think of a namespace as a group, to which classes belong. To use a class in these languages, you have to specify both the class name and the namespace.

 

Objective-C has no notion of namespaces. Instead, we prefix class names with two or three letters to keep them distinct. For example, in this exercise, the class was named
BNRItem
instead of
Item
.

 

Stylish Objective-C programmers always prefix their model and view classes. The prefix is typically related to the name of the application you are developing or the library it belongs to. For example, if I were writing an application named

MovieViewer,

I would prefix all classes with
MV
. Classes that you will use across multiple projects typically bear a prefix that is related to your name (
JC
), your company’s name (
BNR
), or a portable library (a library for dealing with maps might use
MAP
).

 

Controller objects, on the other hand, are typically only used in a single application and do not need a prefix. This isn’t a rule – you can prefix your controller objects if you like, and you definitely should if they will be used in other applications.

 

Notice that Apple’s classes have prefixes, too. Apple’s classes are organized into frameworks (which we’ll talk about in
Chapter 4
), and each framework has its own prefix. For instance, the
UILabel
class belongs to the UIKit framework. The classes
NSArray
and
NSString
belong to the Foundation framework. (The
NS
stands for NeXTSTEP, the platform for which these classes were originally designed.)

 
3
Managing Memory with ARC

In this chapter, you’ll learn how memory is managed in iOS and the concepts that underlie
automatic reference counting
, or ARC. We’ll start with some basics of application memory.

 
The Heap

All Objective-C objects are stored in a part of memory called
the heap
. When we send an
alloc
message to a class, a chunk of memory is allocated from the heap. This chunk includes space for the object’s instance variables.

 

For example, consider an instance of
NSDate
, which represents a specific point in time. An
NSDate
has two instance variables: a
double
that stores the number of seconds since a fixed reference point in time and the
isa
pointer, which every object inherits from
NSObject
. A
double
is eight bytes, and a pointer is 4 bytes, so each time
alloc
is sent to the
NSDate
class, 12 bytes is allocated from the heap for a new
NSDate
object.

 

Consider another example:
BNRItem
. A
BNRItem
has five instance variables: four pointers (
isa
,
itemName
,
serialNumber
, and
dateCreated
) and an
int
(
valueInDollars
). The amount of memory needed for an
int
is four bytes, so the total size of a
BNRItem
is 20 bytes (
Figure 3.1
).

 

Figure 3.1  Byte count of BNRItem and NSDate instances

 

Notice in
Figure 3.1
that the
NSDate
object does not live inside the
BNRItem
. Objects never live inside one another; they exist separately on the heap. Instead, objects keep references to other objects as needed. These references are the pointer instance variables of an object. Thus, when a
BNRItem
’s
dateCreated
instance variable is set, the
address
of the
NSDate
instance is stored in the
BNRItem
, not the
NSDate
itself. So, if the
NSDate
was 10, 20, or even 1000 bytes, it wouldn’t affect the size of the
BNRItem
.)

 
The Stack

There is another part of memory called the
stack
that is separate from the heap. The reason for the names heap and stack has to do with how we visualize them. The heap is a giant heaping mess of objects, and we use pointers to remember where those objects are stored within the heap. The stack, on the other hand, can be visualized as a physical stack of
frames
.

 

When a method (or function) is executed, it allocates a chunk of memory from the stack. This chunk of memory is called a frame, and it stores the values for variables declared inside the method. A variable declared inside a method is called a
local variable
.

 

When an application launches and runs the
main
function, the frame for
main
is put at the bottom of the stack. When
main
calls another method (or function), the frame for that method is added to the top of the stack. Of course, that method could call another method, and so on, until we have a towering stack of frames. Then, as each method or function finishes, its frame is

popped off

the stack and destroyed. If the method is called again, a brand new frame will be allocated and put on the stack.

 

For example, in your
RandomPossessions
application, the
main
function runs
BNRItem
’s
randomItem
method, which in turn runs
BNRItem
’s
alloc
method. The stack would look like
Figure 3.2
. Notice that
main
’s frame stays alive while the other methods are executing because it has not yet finished executing.

 

Figure 3.2  Stack growing and shrinking

 

Recall that the
randomItem
method runs inside of a loop in the
main
function. So with every iteration, the stack grows and shrinks as frames are pushed on and popped off the stack.

 
Pointer Variables and Object Ownership

Pointer variables convey
ownership
of the objects that they point to.

 
  • When a method (or function) has a local variable that points to an object, that method is said to
    own
    the object being pointed to.
 
  • When an object has an instance variable that points to another object, the object with the pointer is said to
    own
    the object being pointed to.
 
 

Think back to your
RandomPossessions
application as a whole. Or, better yet, reopen
RandomPossessions.xcodeproj
and have another look at the code in
main.m
. In this application, an instance of
NSMutableArray
is created in the
main
function, and then 10
BNRItem
instances are added to the array.

 

Figure 3.3
shows the objects in
RandomPossessions
and the pointers that reference them.

 

Figure 3.3  Objects and pointers in RandomPossessions

 

The
NSMutableArray
is pointed to by the local variable
items
within the
main
function, so the
main
function owns the
NSMutableArray
. Each
BNRItem
instance owns the objects pointed to by its instance variables.

 

In addition, the
NSMutableArray
owns the
BNRItem
s. Recall that a collection object, like an
NSMutableArray
, holds pointers to objects instead of actually containing them. These pointers convey ownership: an array owns the objects it points to.

 

The relationship between pointers and object ownership is important for understanding memory management in iOS.

 

Other books

Sir Francis Walsingham by Derek Wilson
T Wave by Steven F. Freeman
The Balance of Silence by S. Reesa Herberth, Michelle Moore
Burn Bright by Marianne de Pierres
On the Edge A Novel by Edward St. Aubyn