Writing the RandomPossessions Tool

Before you dive into the UIKit, the set of libraries for creating iOS applications, you’re going to write a command line tool that will let you focus on the Objective-C language. Open Xcode and select FileNewNew Project.... In the lefthand table in the Mac OS X section, click Application and then select Command Line Tool from the upper panel, as shown in Figure 2.3. Click the Next button.

Figure 2.3  Creating a command line tool

Creating a command line tool

On the next panel, name the product RandomPossessions and choose Foundation as its type (Figure 2.4). 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.

Figure 2.4  Naming the project

Naming the project

One source file (main.m) has been created for you in the RandomPossessions group of the project navigator (Figure 2.5).

Figure 2.5  Project navigator for command line tool template

Project navigator for command line tool template

Click on this file to open it in the editor area, and you’ll see that some code has already been written for you – most notably, a main function that is the entry point of any C (or Objective-C) application.

Time to put your knowledge of Objective-C basics to the test. Delete the line of code that NSLogs Hello, World! and replace it with lines that create and destroy an instance of an NSMutableArray.

#​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​[​]​)​
{​
 ​ ​ ​ ​N​S​A​u​t​o​r​e​l​e​a​s​e​P​o​o​l​ ​*​p​o​o​l​ ​=​ ​[​[​N​S​A​u​t​o​r​e​l​e​a​s​e​P​o​o​l​ ​a​l​l​o​c​]​ ​i​n​i​t​]​;​

 ​ ​ ​ ​/​/​ ​C​r​e​a​t​e​ ​a​ ​m​u​t​a​b​l​e​ ​a​r​r​a​y​,​ ​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​]​;​

 ​ ​ ​ ​/​/​ ​R​e​l​e​a​s​e​ ​t​h​e​ ​a​r​r​a​y​
 ​ ​ ​ ​[​i​t​e​m​s​ ​r​e​l​e​a​s​e​]​;​

 ​ ​ ​ ​/​/​ ​D​o​n​'​t​ ​l​e​a​v​e​ ​i​t​e​m​s​ ​p​o​i​n​t​i​n​g​ ​a​t​ ​f​r​e​e​d​ ​m​e​m​o​r​y​!​
 ​ ​ ​ ​i​t​e​m​s​ ​=​ ​n​i​l​;​


 ​ ​ ​ ​[​p​o​o​l​ ​d​r​a​i​n​]​;​
 ​ ​ ​ ​r​e​t​u​r​n​ ​0​;​
}​

Once you have an instance of NSMutableArray, you can send it messages, like addObject: and insertObject:atIndex:. In this code, the receiver is the items variable that points at the newly instantiated NSMutableArray. Add a few strings to the array instance.

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​[​]​)​
{​
 ​ ​ ​ ​N​S​A​u​t​o​r​e​l​e​a​s​e​P​o​o​l​ ​*​p​o​o​l​ ​=​ ​[​[​N​S​A​u​t​o​r​e​l​e​a​s​e​P​o​o​l​ ​a​l​l​o​c​]​ ​i​n​i​t​]​;​

 ​ ​ ​ ​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​]​;​

 ​ ​ ​ ​[​i​t​e​m​s​ ​r​e​l​e​a​s​e​]​;​
 ​ ​ ​ ​i​t​e​m​s​ ​=​ ​n​i​l​;​

 ​ ​ ​ ​[​p​o​o​l​ ​d​r​a​i​n​]​;​
 ​ ​ ​ ​r​e​t​u​r​n​ ​0​;​
}​

When this application executes, it creates an NSMutableArray and fills it with four NSString instances. However, you need to confirm that you added the strings. In main.m, after adding the final object to the array, loop through every item in the array and print each one to the console.

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​[​]​)​
{​
 ​ ​ ​ ​N​S​A​u​t​o​r​e​l​e​a​s​e​P​o​o​l​ ​*​p​o​o​l​ ​=​ ​[​[​N​S​A​u​t​o​r​e​l​e​a​s​e​P​o​o​l​ ​a​l​l​o​c​]​ ​i​n​i​t​]​;​

 ​ ​ ​ ​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​]​;​
 ​ ​ ​ ​[​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​"​]​;​
 ​ ​ ​ ​[​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​ ​a​r​r​a​y​ ​a​s​ ​d​e​t​e​r​m​i​n​e​d​ ​b​y​ ​s​e​n​d​i​n​g​ ​c​o​u​n​t​ ​t​o​ ​t​h​e​ ​i​t​e​m​s​ ​a​r​r​a​y​
 ​ ​ ​ ​f​o​r​(​i​n​t​ ​i​ ​=​ ​0​;​ ​i​ ​<​ ​[​i​t​e​m​s​ ​c​o​u​n​t​]​;​ ​i​+​+​)​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​W​e​ ​g​e​t​ ​t​h​e​ ​i​t​h​ ​o​b​j​e​c​t​ ​f​r​o​m​ ​t​h​e​ ​a​r​r​a​y​ ​a​n​d​ ​p​a​s​s​ ​i​t​ ​a​s​ ​a​n​ ​a​r​g​u​m​e​n​t​ ​t​o​ ​N​S​L​o​g​,​
 ​ ​ ​ ​ ​ ​ ​ ​/​/​ ​w​h​i​c​h​ ​i​m​p​l​i​c​i​t​l​y​ ​s​e​n​d​s​ ​t​h​e​ ​d​e​s​c​r​i​p​t​i​o​n​ ​m​e​s​s​a​g​e​ ​t​o​ ​t​h​a​t​ ​o​b​j​e​c​t​
 ​ ​ ​ ​ ​ ​ ​ ​N​S​L​o​g​(​@​"​%​@​"​,​ ​[​i​t​e​m​s​ ​o​b​j​e​c​t​A​t​I​n​d​e​x​:​i​]​)​;​
 ​ ​ ​ ​}​

 ​ ​ ​ ​[​i​t​e​m​s​ ​r​e​l​e​a​s​e​]​;​
 ​ ​ ​ ​i​t​e​m​s​ ​=​ ​n​i​l​;​

 ​ ​ ​ ​[​p​o​o​l​ ​d​r​a​i​n​]​;​
 ​ ​ ​ ​r​e​t​u​r​n​ ​0​;​
}​

Click the Run button. It may seem like nothing has happened because the program exits right away, but the log navigator tells another story.

The log navigator stores the build results and console output from each build of your application. To reveal the log navigator, select the Project navigator for command line tool template icon or use the keyboard shortcut Command-7. Select Debug RandomPossessions at the top of the log navigator to see your console output in the editor area (Figure 2.6).

Figure 2.6  Console output

Console output

NSString

Now let’s go back and take a closer look at some of the code in your main function. First, notice the @"One" argument in the first addObject: message sent to items.

[​i​t​e​m​s​ ​a​d​d​O​b​j​e​c​t​:​@​"​O​n​e​"​]​;​

In Objective-C, when you want a hard-coded string, you prefix a character string with an @ symbol. This creates an instance of NSString (another Objective-C class) that holds the character string.

But, wait – aren’t instances created by sending alloc to a class? That is the way most objects are created, but the @ prefix is a special case for the NSString class. It is convenient shorthand for creating strings.

The following code shows three such uses, and each is completely valid Objective-C, where length is an instance method on NSString:

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​!​"​;​
i​n​t​ ​l​e​n​ ​=​ ​[​m​y​S​t​r​i​n​g​ ​l​e​n​g​t​h​]​;​

l​e​n​ ​=​ ​[​@​"​H​e​l​l​o​,​ ​W​o​r​l​d​!​"​ ​l​e​n​g​t​h​]​;​

m​y​S​t​r​i​n​g​ ​=​ ​[​[​N​S​S​t​r​i​n​g​ ​a​l​l​o​c​]​ ​i​n​i​t​W​i​t​h​S​t​r​i​n​g​:​@​"​H​e​l​l​o​,​ ​W​o​r​l​d​!​"​]​;​
l​e​n​ ​=​ ​[​m​y​S​t​r​i​n​g​ ​l​e​n​g​t​h​]​;​

Next, let’s look at the function NSLog we used to print to the console. NSLog takes a variable number of arguments and prints a string to the console. The first argument is required and must be an NSString instance. This instance is called the format string, and it contains text and a number of tokens. Each additional argument passed to the function replaces a token in the format string. The tokens (also called format specifications) must be prefixed with a percent symbol (%), and they specify the type of the argument they correspond to. Here’s 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 order of the arguments matters: the first token is replaced with the second argument (the format string is always the first argument), the second token is replaced with the third argument, and so on. The console output would be

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

In C, there is a function called printf that does the same thing. However, NSLog adds one more token to the available list: %@. When %@ is encountered in the format string, instead of the token being replaced by the corresponding argument, that argument is sent the message description. This method returns an NSString that replaces the token. Because the argument is sent a message, that argument must be an object. As we’ll see shortly, every object implements the method description, so any object will work.

NSArray and NSMutableArray

What exactly is this NSMutableArray you’ve been using? An array is a collection object (also called a container). The Cocoa Touch frameworks provide a handful of collection objects, such as NSDictionary and NSSet, and each has a slightly different use. An array is an ordered list of objects that can be accessed by an index. Other languages might call it a list or a vector. An NSArray is immutable, which means you cannot add or remove objects after the array is instantiated. You can, however, retrieve objects from the array. NSArray’s mutable subclass, NSMutableArray, lets you add and remove objects dynamically.

In Objective-C, an array does not actually contain the objects that belong to it; instead it holds a pointer (a reference) to each object. When an object is added to an array,

 ​ ​ ​ ​[​a​r​r​a​y​ ​a​d​d​O​b​j​e​c​t​:​o​b​j​e​c​t​]​;​

the address of that object in memory is stored inside the array.

So, to recap, in your command line tool, you created an instance of NSMutableArray and added four instances of NSString to it, as shown in Figure 2.7.

Figure 2.7  NSMutableArray instance

NSMutableArray instance

Arrays can only hold references to Objective-C objects. This means primitives and C structures cannot be added to an array. For example, you cannot have an array of ints. Also, because arrays only hold a pointer to an object, a single array can contain objects of different types. This is different from most strongly-typed languages where an array can only hold objects of its declared type.

You can ask an array how many objects it is currently storing by sending it the message count. This information is important because if you ask for an object from an array at an index that is greater than the number of objects in the array, an exception will be thrown. (Exceptions are very bad; they will most likely cause your application to crash. We’ll talk more about exceptions at the end of this chapter.)

 ​ ​ ​ ​i​n​t​ ​n​u​m​b​e​r​O​f​O​b​j​e​c​t​s​ ​=​ ​[​a​r​r​a​y​ ​c​o​u​n​t​]​;​

When an object is added to an array with the message addObject:, it is added at the end of the array. You can also insert objects at a specific index – as long as that index is less than or equal to the current number of objects in the array.

 ​ ​ ​ ​i​n​t​ ​n​u​m​b​e​r​O​f​O​b​j​e​c​t​s​ ​=​ ​[​a​r​r​a​y​ ​c​o​u​n​t​]​;​
 ​ ​ ​ ​[​a​r​r​a​y​ ​i​n​s​e​r​t​O​b​j​e​c​t​:​o​b​j​e​c​t​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​a​t​I​n​d​e​x​:​n​u​m​b​e​r​O​f​O​b​j​e​c​t​s​]​;​

Note that you cannot add nil to an array. If you need to add holes to an array, you must use NSNull. NSNull is an object that represents nil and is used specifically for this task.

 ​ ​ ​ ​[​a​r​r​a​y​ ​a​d​d​O​b​j​e​c​t​:​[​N​S​N​u​l​l​ ​n​u​l​l​]​]​;​

To retrieve the pointer to an object later, you send the message objectAtIndex: to the array

 ​ ​ ​ ​N​S​S​t​r​i​n​g​ ​*​o​b​j​e​c​t​ ​=​ ​[​a​r​r​a​y​ ​o​b​j​e​c​t​A​t​I​n​d​e​x​:​0​]​;​

For readers who know something about retain counts: an object added to an array is sent the message retain. When an object is removed from an array, it is sent the message release. When an array is deallocated, all of its objects are sent the message release. If you don’t know what retain, release, and deallocate mean, that’s okay; you’ll learn about them in the next chapter.

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

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