In Interface Builder

In Interface Builder

Earlier in this chapter, I told you if you want to be able to access the label and text field objects in my ReturnMeTo application, you had to take two steps:

1. Declare an outlet in your code.

2. Use Interface Builder to point the outlet to the label and text fields you created earlier in Interface Builder.

You’ve created the outlets and their accessor methods in your code — I saw you do it in the previous section. Now I’m going to show you how to create the connection in Interface Builder so that when the nib file is loaded, the nib loading code will create these connections automatically, using the accessors you had the compiler create for the label and textField. (aha!) With these connections established, you’ll be able to send messages to your interface objects. (I’ll show you how to receive messages from interface objects a bit later.)

So, it’s connection time.

1. For your ReturnMeTo project, be sure to add the instance variables, @property declaration and @synthesize statement to your code as spelled out in Steps 4 and 7 in the "Adding Outlets to the View Controller" section, earlier in this chapter; then choose FileOSave or press to save what you have done for each file.

You have to save your code; otherwise, Interface Builder won’t be able to find it.

2. In the project window, double-click ReturnMeToViewController. xib to launch Interface Builder.

Interface Builder duly makes an appearance on-screen, with the main nib window and the View window open for inspection. (For more on the mechanics of Interface Builder, see Chapter 5.)

3. Holding down the control key, click the File’s Owner icon in the main nib window and drag it to the label field in the View window, as shown in Figure 7-10.

You need to use the control key here, or you will just end up dragging the File’s Owner icon, rather than initiating a connection.

You should see the label value (650 555 1212) appear when you’re over the label field. (If you remember, that was the value you set when you created the label in Chapter 5.)

Figure 7-10:

Dragging from the File’s Owner to the label.

4. With the cursor still over the label field, let go of the mouse button.

A pop-up menu appears, looking like the one in Figure 7-11.

5. Choose label from the pop-up menu.

Interface Builder now knows that one of the File Owner’s outlets (in this case, the label value I selected in the pop-up menu, which is one of

The ReturnMeToViewController outlets) should point to the label at runtime.

There’s another way to do this, however, one that’s a little more obvious. To see how that method works, check out how I connect the other outlet — the textField outlet — to its text field.

Memory Management

Memory Management

In Chapter 6, I spend a lot of time berating you about memory management — and I promised there that I would make sure to show you how to do this memory-management thing, using a real-world example. I’ll start to keep that promise by explaining the dealloc method created for me by the Xcode template when I

Created the ReturnMeTo application. Now, recall that in Step 9 in the earlier section "Adding Outlets to the View Controller," I asked you to add

[textField release]; [label release];

To the dealloc method, so the end product looks like the following:

- (void)dealloc {

[textField release]; [label release];

[super dealloc];

}

Well, here’s why: Adding these bits of code releases textField and label.

Chapter 6 gave you some handy memory-management rules. Here’s one of them:

You own an object you create with alloc or new or if it contains copy or if you send it a retain message. That means you’re responsible for telling the memory-management system you’re done with it.

In other words, you have to release it when you’re done.

So why, then, you might ask, do I have to release textField and label? If I had created the textField and label using alloc or new, obviously it would be my job to release them. But I didn’t do that — or did I?

No, I didn’t, but what I did do was send a retain message to both text-Field and label.

"Oh, yeah?" "Where?" you might ask.

Check out the @property declarations you made earlier:

@property (nonatomic, retain) UITextField *textField; @property (nonatomic, retain) UILabel *label;

You see, lo and behold, retain.

The impact of adding that simple two-syllable word retain is that any time I assign to that instance variable — assigning a phone number to a label, for example — a retain message will be sent to it — and that is precisely what happens at runtime for the outlets.

Notice that while the dealloc method generated by Xcode for the

ReturnMeToViewController only invoked [super dealloc], the one generated for me in ReturnMeToAppDelegate did more than that.

- (void)dealloc {

[viewController release]; [window release]; [super dealloc];

}

This is because while Xcode didn’t know about the label and textField I was going to create (it can’t read my mind after all), it did know about the window and view controller it created for me, and it created the code to release them in the dealloc method.

Objective-C properties

Objective-C propertiesAs you’ll soon discover, you’re going to use properties a lot. In the previous section, I had you blindly follow me and add the properties. But by now you’ve probably figured out that I don’t believe you should be doing things blindly, so in this section, I get to explain what you need to know about properties.

Now, you may remember that, in object-oriented programming, a class’s instance variables are tucked away inside an object and shouldn’t be accessed directly. If you need to have an instance variable accessible by other objects in your program, you need to create accessor methods for that particular instance variable. (This will sound familiar from the previous section.)

For example, in Chapter 9, you’re going to add an instance variable saved Number, to the ReturnMeToAppDelegate. You’ll do that because you need something to hold the telephone number someone’s supposed to use to call you when he or she finds your lost iPhone. The ReturnMeToAppDelegate saves that number when the application terminates, and loads it when it launches. But the ReturnMeToViewController needs access to that number to display it in the view, and needs to update it when the user enters a new number.

The methods that provide access to the instance variables of an object are called accessor methods, and they effectively get (using a getter method) and set (using a setter method) the values for an instance variable. Although you could code those methods yourself, it can be rather tedious. This is where properties come in. The Objective-C Declared Properties feature provides a simple way to declare and implement an object’s accessor methods. The compiler can synthesize accessor methods for you, according to the way you told it to in the property declaration.

Objective-C creates the getter and setter methods for you by using an @property declaration in the interface file, combined with the @synthesize declaration in the implementation file. The default names for the getter and setter methods associated with a property are whateverTheProperty Namels: for the getter and setWhateverThePropertyNamels: for the setter. (You replace what is in italics with the actual property name.) For example, the accessors generated in our ReturnMeTo application are textField as the getter and setTextField: as the setter. Similarly, the names for the label accessors are label and setLabel: for the getter and setter, respectively.

All that being said, at the end of the day, you need to do three things in your code to have the compiler create accessors for you:

1. Declare an instance variable in the interface file.

2. Add an @property declaration of that instance variable in the same interface file (usually with attributes nonatomic and retain).

This is what you did in Step 4 in the previous section. The declaration specifies the name and type of the property and some attributes that provide the compiler with information about how exactly you want the accessor methods to be implemented.

For example, the declaration

@property (nonatomic, retain) UITextField *textField;

Declares a property named textField, which is a pointer to a UITextField object. As for the two attributes — nonatomic and retain — nonatomic tells the compiler to create an accessor to return the value directly, which is another way of saying that the accessors can be interrupted while in use. (This works fine for applications like this one.)

The second value, retain, tells the compiler to create an access method that sends a retain message to any object that is assigned to this property. This will keep it from being deallocated — having its memory taken back by the iPhone OS to use elsewhere — while you’re still using it. (I go into that a bit more when I explain the dealloc method that Xcode created for us.)

3. Use @synthesize in the implementation file so that Objective-C generates the accessors for you.

The @property declaration (like the two you placed in the interface file in Step 4 in the previous section) only declares that there are accessors. It is the @synthesize statement (like the two you placed in the implementation file in Step 7 in the previous section) that tells the compiler to create them for you. Using @synthesize results in four new methods.

£

TextField setTextField: label setLabel:

If I didn’t use @synthesize, it would be up to me to implement the methods myself, using the attributes in the @property statement. So if I were to write my own accessors, I would be responsible for sending a retain message to the textField or label when it is assigned to the instance variables. While there are circumstances when you do want to do that, I’ll not get into them in this book.

Find

FindXcode can also help you find things in your own project. The submenu accessed by choosing EditOFind provides several options for finding text in your own project.

You will find that, as your classes get bigger, sometimes you’ll want to find a single symbol or all occurrences of a symbol in a file or class. You can easily do that by choosing EditOFindOFind or pressing ^+F, which opens a Find toolbar to help you search the file in the Editor window. In Figure 7-5, for example, I typed viewDidLoad in the Find toolbar, and Xcode found all the instances of viewDidLoad in that file and highlighted them for me.

P ProlocCd MdrMH

- 5.11 ГеЬии ‘ й -

R. rftiijit Л Fllei ▼ KetumMe Го Claim

"Zj Bf штМгТп AppIV irgarr h

М KetomMetaAi>pUe4egat<.m W| RcLuuiUeTaV1cwCunLiuller. li _и] Rem m WpTn V1 ewfn nrm II» r. m

► ij_] Ottier Source s

* „ Reiuuriei

LlenimMpTaVlenCnnrrollrr. vl *] MainWimloA. xib | ReluinMeTu-infe. pliU •j Phnnr png J*] ReturnMeTo >con. pr-q

► C^FMmewortu

* Prwfiictt

► ©Taroeti

И Executable! * Find Result*

► LJi BoiAmarki

► t. SCM

Ф Crajprt Symbelt

► Ij^gj Implementation File i

► Ш Interface Buiidtf Filts

Ж

Figure 7-4:

Right-click UI

Application Delegate.

P ci u rriMe To ft ppDe i&n аге. h – Rciuinuefo

1ч О

Q* Suing Mantling Searrh * Cndf О

KeturnHe 1 oAppOeieiMte. li

Cut

Copy

Paste

•leport – L

► j^iJlionBelegalo

Sinter i Jt.( UlWinri Returil

«Property

Gprnprrty (—

TeuCnntrnller *inewt т

Balance

Re-Indent Selection Shift Selection Right Shift Selection 1 eft

Refaetor…

Next Completion Completion List Select Next Placeholder

Edit All In bcope

Code Folding Menage Bubble*;

Open As

Open in Separate editor Reveal Jn Tinder Reveal Jn Croup Tree Add to Bookmarks

Find in Project ►

Find Text in Documentation Jump to Definition Search in Spotlight

Cet Info

~ Make New Mail Note

Jr Add to ITunes as a Spoken Track

Figure 7-5:

Finding

View DidLoad in a file.

You can also use Find to go through your whole project by choosing EditOFindOFind in Project or by pressing ^+Shift+F. I pressed ^+Shift+F, which opened the window shown in Figure 7-6. I typed

ReturnMeToViewController, and then in the drop-down menu, I selected In Project. You can specify in what sets of files (open project files, and so on) you want to search. (A great feature for tracking down something in your code — you’re sure to use it often.)

If you select a line in the top pane, as you can see in Figure 7-6, the file in which that instance occurs is opened in the bottom pane and the reference highlighted.

AddINg Outlets to the View Controller

Now that you have some idea of how to use the Xcode editor, it’s time to write some code. Before taking you on our editor tour, I mentioned that one of the things I needed to do was add outlets to my ReturnMeTo application. That’s what you’re going to do now — add outlets to the

ReturnMeToViewController. Here’s how:

1. Go to the Xcode project window and, in the Groups & Files pane, click the triangle next to Classes to expand the folder.

2. From the Classes folder, select ReturnMeToViewController. h — the header file for ReturnMeToViewController.

The contents of the file appear in the main display pane of the Xcode editor, as shown in Figure 7-7 (Of course yours won’t have all of that code in it yet — you’ll be entering it in Step 4.)

Figure 7-7:

ReturnMe ToView Controller. h.

3. Look for the following lines of code in the header:

#import <UIKit/UIKit. h>

@interface ReturnMeToViewController: UIViewController{ }

@end

Got it? Great.

4. Type the following four lines of code between UIViewController{ and @end (the curly brace you see below the last IBOutlet and first @property statements will already be there).

IBOutlet UITextField *textField;

IBOutlet UILabel *label; }

@property (nonatomic, retain) UITextField *textField; @property (nonatomic, retain) UILabel *label;

When you’re done typing, your code should look exactly like Figure 7-7.

The first two lines of code here declare the outlets, which will automatically be initialized with a pointer to the text field (textField) and label objects (label) when the application is launched. But while this will happen automatically, it won’t automatically happen automatically. I have to help it out a bit.

In procedural programming, variables are generally fair game for all. But in object-oriented programming, a class’s instance variables are tucked away inside an object and shouldn’t be accessed directly. The only way

For them to be initialized is for you to create what are called accessor methods, which allow the specific instance variable of an object to be read and (if you want) updated. Creating accessor methods is a two-step process that begins with a @property declaration, which tells the compiler that there are accessor methods.

And that is what I did above; I coded corresponding @property declarations for each IBOutlet declaration. You’ll notice there are some arguments to the @property declaration. These specify how the accessor methods are to behave — I explain exactly what that means in the next section. For now, just know that you need to add them.

5. Go back to the Classes folder in the Groups & Files listing and select

ReturnMeToViewController. m — the implementation file for ReturnMeToViewController.

6. Look for the following lines of code in the implementation file:

#import "ReturnMeToViewController. h"

@implementation ReturnMeToViewController They’re pretty much right at the top.

7. Type the following two lines of code after @implementation ReturnMeToViewController and before anything else.

©synthesize textField; ©synthesize label;

When you’re done, your code should like what you see in Figure 7-8.

While the @property declaration tells the compiler that there are accessor methods, they still have to be created. In the good-old days, you had to code these accessor methods yourself and, in a large program, it got to be very tedious. Fortunately, Objective-C will create these accessor methods for you whenever you include an @synthesize statement for a property.

That is what you did above. The two @synthesize statements tell the compiler to create two accessor methods for you — one for each @property declaration.

8. Scroll down the code for ReturnMeToViewController. m until you reach the following lines:

- (void)dealloc {

[super dealloc];

}

You can use to find something in a single file, as opposed to Shift+^+F, which finds it in all project files.

Figure 7-8:

Completing the addition of the accessors.

9. Enter the following two lines of code between the - (void)dealloc { and [super dealloc]; lines:

[textField release]; [label release];

The new code should look like what you see in Figure 7-9.

Those of you who remember my obsession with memory management from previous chapters will recognize release as a tool for freeing up no-longer-needed memory commitments. (Those of you who have not yet heard my memory-management stump speech will get a chance to hear it later in this chapter.)

That’s it. You’ve added outlets to your view controller. Step back and admire your handiwork. Then move on to the next section and see how the little snippets of code you added above to your ReturnMeToViewController. m and ReturnMeToViewController. h files tie in with the basic principles of programming using the Objective-C language.

■ Re 1 ur n MrTnVi i-wConl roller

- RrturnMrTn

Simulator * i. l | Debug

Tfc т m

Vs

О

I’Q – «ring Matching

Orel view

Aitiun Eieakfiolntv

Uil-d and Run

Taifn Inlia

Search

Cruupi& Fries

Т ^ RrturnMrTn TQJ unit;

ReluiiiMcToAupDelegjte. il _ Rrr» rnMrTnAppDrIf garr m м, Ketu гпМе Г OVu-wCo’itroiler. h ы RcturnMeTuVmnCunliDller. ni ► OS Other 5аигг*л * Qj Resources

•.’ RcluiiiMeToV№inCiHiliuller. j(ib

RfiumMt-TaVlrwrnmrnllM. m

. с. I. • a

T*uprr ЛмПлг)[

■I >

-(UUCL)textl leldihoutdReturn: шло"1 jeld «Hlflextl ield (

С

Ь

J RrturnMrTn Irnn png » Frameworks H IPmdusts

► Targrts

• Lxecutitiles

* 4, Find Results

P и ftnali marts

► " SCM

M

Figure 7-9:

Doing a little memory management.

Help menu

Help menuThe Help menu search field also lets you search Xcode documentation as well as open the documentation window and Quick Help.

You can also right-click on a symbol and get a pop-up menu that gives you similar options to what you see in the Help menu (and other related functions). This is shown in Figure 7-4.

Documentation window

Documentation windowThe documentation window lets you browse and search items that are part of the ADC Reference Library as well as any third-party documentation you have installed.

You access the documentation by pressing ^+Option+double-clicking a symbol to get access to an API reference (among other things) that provides information about the symbol. This enables you to get the documentation about a method to find out more about it or the methods and properties in a framework class. In Figure 7-3, I pressed ^+Option+double-clicked UIApplicationDelegate.

Using the documentation window, you can browse and search the developer documentation — the API references, guides, and article collections about particular tools or technologies — installed on your computer.

It is the go-to place for getting documentation about a method or more info about the methods and properties in a framework class. (Using the API reference is how I discovered that a view has a frame, which I’ll use to determine how much to scroll the view to keep the text field visible in Chapter 8.)

« n Л

• о- ‘">"-’

Влк/Ferward Home Btrakmaiks

UlApplli

(o. (JtAppUtationDEKgaw

Ftin All Dec Serf т All | ллдиадг". т

Protocol Reference

UlAppit с ation Deteqste

* Table of Curitenls

Г Htle

UlApplirntinnllrlpgilr Protarnl Refemve

Titkt

Methods

COMPANION GUIDE.

AppllraUnn Pw

Figure 7-3:

The documentation window.

»Full T. tt .

Ь Leainlnu ObjeiUve-C Л Prime i a rnmmnniraiLig Wlrh (Mijrrri

11 UIApplicationDelegate Protocol Referente UlAppliuUunDelegale PipUtujI Relerenie

I; LHWi Framework Reference

■ t ustnmmryj ttie Appbrahnn llPEegale

■ Hello, woridi source (.ode b Cuite listing 11 I ПАррПг. шлп flats Re ft rrnre 4 Vicv» transitions – /LtiueJ/ViewIran. R BjltcyStatus – /CliiiM/SiWei*5U(tJ…

Accelerome«iCraph – ,’AppDelegiie>.

■ Tnurhr-s ;Cla«rs/TnurlsnApjinple R. rablebearcn – /AppDelegate. h

■ AMeniateViewi - I‘AupDclcsalc. li HrarterFriatfr /Appt)plrgarp h

■ WhlrhWaylillp – i’( lasses/WhichWayl С CLSyriie – /Classes/CLSpriteAiipDele И AtLessury – i2 AppDclegatc. il

■ ’ I aur. rhMe ^Cla^ses/tauivtiMrApp

■ MJOfllUieKender I est – /Clawes/Atl…

■ SysSiwrid -/Classes/SysSuundApuO. . ! Scrolling I’AppDdtOltC-h a Mailt ompnser – i’( lasses, i HaiH гапр

UIApplicationDelegate Protocol Reference

Conforms to

№Otyect

Frjmrwork /Sy. trmjl liHiiry/Frikmrmirk%/ll(Ki1.fr. imFW[irk

Availability

Available in ifhone (А ли and later.

Companion guide

IPIione Application Program mine Guide

Declared in

LltAppliratiiin. h

Related sample code

App Pre fj

HeaderFooter

ScmltVirvrtuitr

IpeakHere TableVlew^uite

Overview

Important: This is a preliminary document for an API or rerhnnlogv |n development Alrhnugli Thli dorumpnr hai been ■■* tcdinital accuracy. it ii not final. Apple ii

_ iPfione г)1! + 1 ithrary tapirs

The header file for a symbol

The header file for a symbolHeaders are a big deal in code because they’re the place where you find the class declaration, which includes all of its instance variables and method declarations. To get the header file for a symbol, press ^+double-click the symbol in the Text Editor. For example, see Figure 7-2, where I pressed ^ and then double-clicked UIApplicationDelegate.

This works for the classes you create as well.

Ф lllApplkjlian. h – ArliirnUrTn

| Simulator ■- i. l I Debug | Й " j » j

El"

A

Build and Run

Ociuin & Files

V Ej RrmrnMpTn

- RcluiiiMcTuApfiDcleyjtc. Ii

М RrturnMrlnApfiClrlrgalr m. i RetijrnMeToViertControlltr. il ы ReturnMeToViertliHitrolltr. m

► (Jj Other yiurcn

* r_j hujuiut, v

RcluinMcTB-lnlu. il

- Ptione. pnfl » KcturnMeto icon-pr

► Fr on wmirtu

► CTl Prariitn-t

* 1У’ targets

► bieiifljJifes т C^ Flnri RcMjIri » и Booknurti

P ; SCM

Щ Prajrn Symtwili

* ImpiemenlaJujn Files

► Mb Intcrf jce Builder Fries

Figure 7-2:

The header file for UI Application Delegate.

^ Code

RnMrTfiAfipOplpgxrp h

File Name

Quick Help

Quick HelpQuick Help is an unobtrusive window that provides the documentation for a single symbol. It pops up inline, although you can use Quick Help as a symbol inspector (which stays open) by moving the window after it opens. You can also customize the display in Documentation preferences in Xcode preferences.

To get Quick Help for a symbol, double-click the symbol in the Text Editor (in this case UIApplicationDelegate; see Figure 7-1).

Figure 7-1:

Getting Quick Help.

Accessing Documentation

Accessing DocumentationLike many developers, you may find yourself wanting to dig deeper when it comes to a particular bit of code. That’s when you really appreciate Xcode’s Quick Help, header file access, Documentation window, Help menu, and Find tools. With these tools, you can quickly access the documentation for a particular class, method, or property.

To see how this works, let’s say I have the project window open with the code displayed in Figure 7-1. What if I wanted to find out more about

UIApplicationDelegate?

The Xcode Code Editor

The Xcode Code EditorThe main tool you use to write code for an iPhone application is the Xcode text editor. Apple has gone out of its way to make the text editor as user-friendly as possible, as evidenced by the following list of (quite convenient) features:

 Code Sense: As you type code, you can have the Editor help by inserting text that completes the name of whatever Xcode thinks you’re going to enter.

Using Code Sense can be really useful, especially if you’re like me and forget exactly what the arguments are for a function. When Code Sense is active (it is by default), Xcode uses the text you typed, as well as the context within which you typed it, to provide suggestions for completing what it thinks you’re going to type. You can accept suggestions by pressing Tab or Return. You may also display a list of completions by pressing Escape.

 Code Folding: With code folding, you can collapse code that you’re not working on and display only the code that requires your attention. You do this by clicking in the column to the left of the code you want to hide.

 Switching between header and implementation windows: On the

Toolbar above the code editor, you click the last icon before the lock to switch from. h to. m (header and implementation), and vice versa. While the header lets you see the class’s instance variables and method declarations, you find your actual code in the implementation file. If you look in the Groups & Files pane of the project window, you can see the separate .h and. m files for the four classes we have started with.

 Launching a file in a separate window: Double-click the filename to launch the file in a new window. This enables you folks with big monitors, or multiple monitors, to look at more than one file at a time. You could, for example, look at the method of one class and the method it invokes in the same, or even a different class.