Beginning RandomItems

This new project is not an iOS application; it is a command-line program. Building a command line program will let you focus on Objective-C without the distraction of a user interface. Still, the concepts that you will learn here and in Chapter 3 are critical for iOS development. You will get back to building iOS applications in Chapter 4.

Open Xcode and select FileNewProject.... In the lefthand table in the OS X section, click Application and then select Command Line Tool from the upper panel, as shown in Figure 2.3. Then click Next.

Figure 2.3  Creating a command line tool

Creating a command line tool

On the next sheet, name the product RandomItems and choose Foundation as its type (Figure 2.4).

Figure 2.4  Naming the project

Naming the project

Click Next and you will be prompted to save the project. Save it some place safe – you will be reusing parts of this code in future projects.

In the initial version of RandomItems, you will create an array of four strings. An array is an ordered list of pointers to other objects. Pointers in an array are accessed by an index. (Other languages might call it a list or a vector.) Arrays are zero-based; the first item in the array is always at index 0.

After the array is created, you will loop through the array and print each string. Its output will appear in Xcode’s console:

Figure 2.5  Console output

Console output

Your program will need five objects: one instance of NSMutableArray and four instances of NSString (Figure 2.6).

Figure 2.6  NSMutableArray instance containing pointers to NSString instances

NSMutableArray instance containing pointers to NSString instances

In Objective-C, an array does not contain the objects that belong to it; instead it holds a pointer to each object. When an object is added to an array, the address of that object in memory is stored inside the array.

Now let’s consider the NSMutableArray and NSString classes. NSMutableArray is a subclass of NSArray. Classes exist in a hierarchy, and every class has exactly one superclass – except for the root class of the entire hierarchy: NSObject. A class inherits the behavior of its superclass.

Figure 2.7 shows the class hierarchy for NSMutableArray and NSString along with a few methods implemented by each class.

Figure 2.7  Class hierarchy

Class hierarchy

As the top superclass, NSObject’s role is to implement the basic behavior of every object in Cocoa Touch. Every class inherits the methods and instance variables defined in NSObject. Two methods that NSObject implements are alloc and init (Figure 2.7). Thus, these methods can be used to create an instance of any class.

A subclass adds methods and instance variables to extend the behavior of its superclass:

  • NSString adds behavior for storing and handling strings, including the method length that returns the number of characters in a string.

  • NSArray adds behavior for ordered lists, including accessing an object at a given index (objectAtIndex:) and getting the number of objects in an array (count).

  • NSMutableArray extends NSArray’s abilities by adding the abilities to add and remove pointers.

Creating and populating an array

Let’s use these classes in some real code. In the project navigator, find and select the file named main.m. When it opens, you will see that some code has been written for you – most notably, a main function that is the entry point of any C or Objective-C application.

In main.m, delete the line of code that NSLogs Hello, World! and replace it with code that creates an instance of NSMutableArray, adds a total of four objects to the mutable array, and then destroys the array.

#​i​m​p​o​r​t​ ​<​F​o​u​n​d​a​t​i​o​n​/​F​o​u​n​d​a​t​i​o​n​.​h​>​

i​n​t​ ​m​a​i​n​ ​(​i​n​t​ ​a​r​g​c​,​ ​c​o​n​s​t​ ​c​h​a​r​ ​*​ ​a​r​g​v​[​]​)​
{​
 ​ ​ ​ ​@​a​u​t​o​r​e​l​e​a​s​e​p​o​o​l​ ​{​

 ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​i​n​s​e​r​t​ ​c​o​d​e​ ​h​e​r​e​.​.​.​
 ​ ​ ​ ​ ​ ​ ​ ​N​S​L​o​g​(​@​"​H​e​l​l​o​,​ ​W​o​r​l​d​!​"​)​;​
 ​ ​ ​ ​ ​ ​ ​ ​
 ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​C​r​e​a​t​e​ ​a​ ​m​u​t​a​b​l​e​ ​a​r​r​a​y​ ​o​b​j​e​c​t​,​ ​s​t​o​r​e​ ​i​t​s​ ​a​d​d​r​e​s​s​ ​i​n​ ​i​t​e​m​s​ ​v​a​r​i​a​b​l​e​
 ​ ​ ​ ​ ​ ​ ​ ​N​S​M​u​t​a​b​l​e​A​r​r​a​y​ ​*​i​t​e​m​s​ ​=​ ​[​[​N​S​M​u​t​a​b​l​e​A​r​r​a​y​ ​a​l​l​o​c​]​ ​i​n​i​t​]​;​

 ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​S​e​n​d​ ​t​h​e​ ​m​e​s​s​a​g​e​ ​a​d​d​O​b​j​e​c​t​:​ ​t​o​ ​t​h​e​ ​N​S​M​u​t​a​b​l​e​A​r​r​a​y​ ​p​o​i​n​t​e​d​ ​t​o​
 ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​b​y​ ​t​h​e​ ​v​a​r​i​a​b​l​e​ ​i​t​e​m​s​,​ ​p​a​s​s​i​n​g​ ​a​ ​s​t​r​i​n​g​ ​e​a​c​h​ ​t​i​m​e​
 ​ ​ ​ ​ ​ ​ ​ ​[​i​t​e​m​s​ ​a​d​d​O​b​j​e​c​t​:​@​"​O​n​e​"​]​;​
 ​ ​ ​ ​ ​ ​ ​ ​[​i​t​e​m​s​ ​a​d​d​O​b​j​e​c​t​:​@​"​T​w​o​"​]​;​
 ​ ​ ​ ​ ​ ​ ​ ​[​i​t​e​m​s​ ​a​d​d​O​b​j​e​c​t​:​@​"​T​h​r​e​e​"​]​;​

 ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​S​e​n​d​ ​a​n​o​t​h​e​r​ ​m​e​s​s​a​g​e​,​ ​i​n​s​e​r​t​O​b​j​e​c​t​:​a​t​I​n​d​e​x​:​,​ ​t​o​ ​t​h​a​t​ ​s​a​m​e​ ​a​r​r​a​y​ ​o​b​j​e​c​t​
 ​ ​ ​ ​ ​ ​ ​ ​[​i​t​e​m​s​ ​i​n​s​e​r​t​O​b​j​e​c​t​:​@​"​Z​e​r​o​"​ ​a​t​I​n​d​e​x​:​0​]​;​

 ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​D​e​s​t​r​o​y​ ​t​h​e​ ​m​u​t​a​b​l​e​ ​a​r​r​a​y​ ​o​b​j​e​c​t​
 ​ ​ ​ ​ ​ ​ ​ ​i​t​e​m​s​ ​=​ ​n​i​l​;​
 ​ ​ ​ ​ ​ ​ ​ ​
 ​ ​ ​ ​}​
 ​ ​ ​ ​r​e​t​u​r​n​ ​0​;​
}​

The objects that you have added and inserted into the array are instances of NSString. You can create an instance of NSString by prefixing a character string with an @ symbol:

N​S​S​t​r​i​n​g​ ​*​m​y​S​t​r​i​n​g​ ​=​ ​@​"​H​e​l​l​o​,​ ​W​o​r​l​d​!​"​;​

Iterating over an array

Now that you have an items array with strings in it, you are going to iterate over the array, access each string, and output it to the console.

You could write this operation as a for loop:

f​o​r​ ​(​i​n​t​ ​i​ ​=​ ​0​;​ ​i​ ​<​ ​[​i​t​e​m​s​ ​c​o​u​n​t​]​;​ ​i​+​+​)​ ​{​
 ​ ​ ​ ​N​S​S​t​r​i​n​g​ ​*​i​t​e​m​ ​=​ ​[​i​t​e​m​s​ ​o​b​j​e​c​t​A​t​I​n​d​e​x​:​i​]​;​
 ​ ​ ​ ​N​S​L​o​g​(​@​"​%​@​"​,​ ​i​t​e​m​)​;​
}​

Because arrays are zero-based, the counter starts at 0 and stops at one less than the result of sending the items array the message count. Within the loop, you then send the message objectAtIndex: to retrieve the object at the current index before printing it out.

The information returned from count is important because if you ask an array for an object at an index that is equal to or greater than the number of objects in the array, an exception will be thrown. (In some languages, exceptions are thrown and caught all the time. In Objective-C, exceptions are considered programmer errors and should be fixed in code instead of handled at runtime. We will talk more about exceptions at the end of this chapter.)

This code would work fine, but Objective-C provides a better option for iterating over an array called fast enumeration. Fast enumeration is shorter syntax than a traditional for loop and far less error-prone. In some cases, it will be faster.

In main.m, add the following code that uses fast enumeration to iterate over the items array.

i​n​t​ ​m​a​i​n​ ​(​i​n​t​ ​a​r​g​c​,​ ​c​o​n​s​t​ ​c​h​a​r​ ​*​ ​a​r​g​v​[​]​)​
{​
 ​ ​ ​ ​@​a​u​t​o​r​e​l​e​a​s​e​p​o​o​l​ ​{​

 ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​C​r​e​a​t​e​ ​a​ ​m​u​t​a​b​l​e​ ​a​r​r​a​y​ ​o​b​j​e​c​t​,​ ​s​t​o​r​e​ ​i​t​s​ ​a​d​d​r​e​s​s​ ​i​n​ ​i​t​e​m​s​ ​v​a​r​i​a​b​l​e​
 ​ ​ ​ ​ ​ ​ ​ ​N​S​M​u​t​a​b​l​e​A​r​r​a​y​ ​*​i​t​e​m​s​ ​=​ ​[​[​N​S​M​u​t​a​b​l​e​A​r​r​a​y​ ​a​l​l​o​c​]​ ​i​n​i​t​]​;​

 ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​S​e​n​d​ ​t​h​e​ ​m​e​s​s​a​g​e​ ​a​d​d​O​b​j​e​c​t​:​ ​t​o​ ​t​h​e​ ​N​S​M​u​t​a​b​l​e​A​r​r​a​y​ ​p​o​i​n​t​e​d​ ​t​o​
 ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​b​y​ ​t​h​e​ ​v​a​r​i​a​b​l​e​ ​i​t​e​m​s​,​ ​p​a​s​s​i​n​g​ ​a​ ​s​t​r​i​n​g​ ​e​a​c​h​ ​t​i​m​e​
 ​ ​ ​ ​ ​ ​ ​ ​[​i​t​e​m​s​ ​a​d​d​O​b​j​e​c​t​:​@​"​O​n​e​"​]​;​
 ​ ​ ​ ​ ​ ​ ​ ​[​i​t​e​m​s​ ​a​d​d​O​b​j​e​c​t​:​@​"​T​w​o​"​]​;​
 ​ ​ ​ ​ ​ ​ ​ ​[​i​t​e​m​s​ ​a​d​d​O​b​j​e​c​t​:​@​"​T​h​r​e​e​"​]​;​

 ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​S​e​n​d​ ​a​n​o​t​h​e​r​ ​m​e​s​s​a​g​e​,​ ​i​n​s​e​r​t​O​b​j​e​c​t​:​a​t​I​n​d​e​x​:​,​ ​t​o​ ​t​h​a​t​ ​s​a​m​e​ ​a​r​r​a​y​ ​o​b​j​e​c​t​
 ​ ​ ​ ​ ​ ​ ​ ​[​i​t​e​m​s​ ​i​n​s​e​r​t​O​b​j​e​c​t​:​@​"​Z​e​r​o​"​ ​a​t​I​n​d​e​x​:​0​]​;​

 ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​F​o​r​ ​e​v​e​r​y​ ​i​t​e​m​ ​i​n​ ​t​h​e​ ​i​t​e​m​s​ ​a​r​r​a​y​ ​.​.​.​
 ​ ​ ​ ​ ​ ​ ​ ​f​o​r​ ​(​N​S​S​t​r​i​n​g​ ​*​i​t​e​m​ ​i​n​ ​i​t​e​m​s​)​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​L​o​g​ ​t​h​e​ ​d​e​s​c​r​i​p​t​i​o​n​ ​o​f​ ​i​t​e​m​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​N​S​L​o​g​(​@​"​%​@​"​,​ ​i​t​e​m​)​;​
 ​ ​ ​ ​ ​ ​ ​ ​}​

 ​ ​ ​ ​ ​ ​ ​ ​i​t​e​m​s​ ​=​ ​n​i​l​;​
 ​ ​ ​ ​}​
 ​ ​ ​ ​r​e​t​u​r​n​ ​0​;​
}​

Fast enumeration has a limitation: you cannot use it if you need to add or remove objects within the loop. Trying to do so will cause an exception to be thrown. If you need to add or remove objects, you must use a regular for loop with a counter variable.

Build and run the application (Command-R). A new pane will appear at the bottom of the Xcode window. This is the debug area. On the righthand side of this area is the console and your output.

Figure 2.8  Output in console

Output in console

If you need to, you can resize the debug area and its panels by dragging their frames. (In fact, you can resize any area in the workspace window this way.)

You have completed the first phase of the RandomItems program. Before you continue with the next phase, let’s take a closer look at the NSLog function and format strings.

Format strings

NSLog() takes a variable number of arguments and prints a string to the log. In Xcode, the log appears in the console. The first argument of NSLog() is required. It is an instance of NSString and is called the format string.

A format string contains text and a number of tokens. Each token (also called a format specification) is prefixed with a percent symbol (%). Each additional argument passed to the function replaces a token in the format string.

Tokens specify the type of the argument that they correspond to. Here is an example:

i​n​t​ ​a​ ​=​ ​1​;​
f​l​o​a​t​ ​b​ ​=​ ​2​.​5​;​
c​h​a​r​ ​c​ ​=​ ​'​A​'​;​
N​S​L​o​g​(​@​"​I​n​t​e​g​e​r​:​ ​%​d​ ​F​l​o​a​t​:​ ​%​f​ ​C​h​a​r​:​ ​%​c​"​,​ ​a​,​ ​b​,​ ​c​)​;​

The output would be

I​n​t​e​g​e​r​:​ ​1​ ​F​l​o​a​t​:​ ​2​.​5​ ​C​h​a​r​:​ ​A​

Objective-C format strings work the same way as in C. However, Objective-C adds one more token: %@. This token corresponds to an argument whose type is a pointer to any object.

When %@ is encountered in the format string, instead of the token being replaced by the corresponding argument, that argument is sent the message description. The description method returns an instance of NSString that replaces the token.

Because the argument that corresponds to the %@ token is sent a message, that argument must be an object. Back in Figure 2.7, you can see that description is a method on the NSObject class. Thus, every class implements description, which is why you can use the %@ token with any object.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset