About Creating Your First iOS App

advertisement
About Creating Your First iOS App
Your First iOS App introduces you to the Three Ts of iOS app development:
 Tools. How to use Xcode to create and manage a project.
 Technologies. How to create an app that responds to user input.
 Techniques. How to take advantage of some of the fundamental design patterns that underlie all iOS app development.
After you complete all the steps in this tutorial, you’ll have an app that looks something like this:
As you can see above, there are three main user interface elements in the app that you create:
 A text field (in which the user enters information)
 A label (in which the app displays information)
 A button (which causes the app to display information in the label)
When you run the finished app, you click inside the text field to reveal the system-provided keyboard. After you use the keyboard to
type your name, you dismiss it (by clicking its Done key) and then you click the Hello button to see the string “Hello, Your Name!“ in
the label between the text field and the button.
Later in Start Developing iOS Apps Today you will work through another tutorial, Internationalize Your App, and in the process add a
Chinese localization to the app you will create in this tutorial.
To benefit from this tutorial, it helps to have some familiarity with the basics of computer programming in general and with objectoriented programming and the Objective-C language in particular. If you haven’t used Objective-C before, don’t worry if the code in
this tutorial is hard to understand. When you finish Start Developing iOS Apps Today, you’ll understand the code much better.
Getting Started
To create the iOS app in this tutorial, you need Xcode 4.3 or later. Xcode is Apple’s integrated development environment (or IDE) for
both iOS and Mac OS X development. When you install Xcode on your Mac, you also get the iOS SDK, which includes the
programming interfaces of the iOS platform.
Create and Test a New Project
To get started developing your app, you create a new Xcode project.
To create a new project
1.
Open Xcode (by default it’s in /Applications).
If you’ve never created or opened a project in Xcode before, you should see a Welcome to Xcode window similar to this:
If you’ve created or opened a project in Xcode before, you might see a project window instead of the Welcome to Xcode window.
2.
In the Welcome to Xcode window, click “Create a new Xcode project” (or choose File > New > New project).
Xcode opens a new window and displays a dialog in which you can choose a template. Xcode includes several built-in app templates
that you can use to develop common styles of iOS apps. For example, the Tabbed template creates an app that is similar to iTunes and
the Master-Detail template creates an app that is similar to Mail.
3.
4.
In the iOS section at the left side of the dialog, select Application.
In the main area of the dialog, select Single View Application and then click Next.
A new dialog appears that prompts you to name your app and choose additional options for your project.
5.
Fill in the Product Name, Company Identifier, and Class Prefix fields.
You can use the following values:
o Product Name: HelloWorld
o Company Identifier: Your company identifier, if you have one. If you don’t have a company identifier, you can use edu.self.
o Class Prefix: HelloWorld
Note: Xcode uses the product name you entered to name your project and the app. Xcode uses the class prefix name to name the
classes it creates for you. For example, Xcode automatically creates an app delegate class and names it
HelloWorldAppDelegate. If you enter a different value for the class prefix, then the app delegate class is named
YourClassPrefixNameAppDelegate. (You’ll learn more about the app delegate in “Find Out How an App Starts Up.”)
To keep things simple, this tutorial assumes that you named your product HelloWorld and that you used HelloWorld for the
class prefix value.
6.
7.
8.
In the Device Family pop-up menu, make sure that iPhone is chosen.
Make sure that the Use Storyboard and Use Automatic Reference Counting options are selected and that the Include Unit
Tests option is unselected.
Click Next.
Another dialog appears that allows you to specify where to save your project.
9.
Specify a location for your project (leave the Source Control option unselected) and then click Create.
Xcode opens your new project in a window (called the workspace window), which should look similar to this:
Take a few moments to familiarize yourself with the workspace window that Xcode opens for you. You’ll use the buttons and areas
identified in the window below throughout the rest of this tutorial.
If the utilities area in your workspace window is already open (as it is in the window shown above), you can close it for now because
you won’t need it until later in the tutorial. The rightmost View button controls the utilities area. When the utilities area is visible, the
button looks like this:
If necessary, click the rightmost View button to close the utilities area.
Even though you haven’t yet written any code, you can build your app and run it in the Simulator app that is included in Xcode. As its
name implies, Simulator allows you to get an idea of how your app would look and behave if it were running on an iOS-based device.
To run your app in Simulator
1.
Make sure that the Scheme pop-up menu in the Xcode toolbar has HelloWorld > iPhone 6.0 Simulator chosen.
If the pop-up menu does not display that choice, open it and choose iPhone 6.0 Simulator from the menu.
2.
Click the Run button in the Xcode toolbar (or choose Product > Run).
Xcode updates you on the build process.
After Xcode finishes building your project, Simulator should start automatically. Because you specified an iPhone product (rather
than an iPad product), Simulator displays a window that looks like an iPhone. On the simulated iPhone screen, Simulator opens your
app, which should look like this:
Right now, your app is not very interesting: it simply displays a blank white screen. To understand where the white screen comes
from, you need to learn about the objects in your code and how they work together to start the app. For now, quit Simulator (choose
iOS Simulator > Quit iOS Simulator; make sure that you don’t quit Xcode).
Find Out How an App Starts Up
Because you based your project on an Xcode template, much of the basic app environment is automatically set up when you run the
app. For example, Xcode creates an application object which, among a few other things, establishes the run loop (a run loop registers
input sources and enables the delivery of input events to your app). Most of this work is done by the UIApplicationMain
function, which is supplied for you by the UIKit framework and is automatically called in your project’s main.m source file.
Note: The UIKit framework provides all the classes that an app needs to construct and manage its user interface. The UIKit
framework is just one of many object-oriented frameworks provided by Cocoa Touch, which is the app environment for all iOS apps.
To look at the main.m source file
1.
Make sure the project navigator is open in the navigator area.
The project navigator displays all the files in your project. If the project navigator is not open, click the leftmost button in the
navigator selector bar:
2.
3.
Open the Supporting Files folder in the project navigator by clicking the disclosure triangle next to it.
Select main.m.
Xcode opens the source file in the main editor area of the window, which should look similar to this:
The main function in main.m calls the UIApplicationMain function within an autorelease pool:
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([HelloWorldAppDelegate
class]));
}
The @autoreleasepool statement supports the Automatic Reference Counting (ARC) system. ARC provides automatic objectlifetime management for your app, ensuring that objects remain in existence for as long as they're needed and no longer.
The call to UIApplicationMain creates an instance of the UIApplication class and an instance of the app delegate (in this
tutorial, the app delegate is HelloWorldAppDelegate, which is provided for you by the Single View template). The main job of
the app delegate is to provide the window into which your app’s content is drawn. The app delegate can also perform some app
configuration tasks before the app is displayed. (Delegation is a design pattern in which one object acts on behalf of, or in
coordination with, another object.)
In an iOS app, a window object provides a container for the app’s visible content, helps deliver events to app objects, and helps the
app respond to changes in the device’s orientation. The window itself is invisible.
The call to UIApplicationMain also scans the app’s Info.plist file. The Info.plist file is an information property list—
that is, a structured list of key-value pairs that contains information about the app such as its name and icon.
To look at the property list file
 In the Supporting Files folder in the project navigator, select HelloWorld-Info.plist.
Xcode opens the Info.plist file in the editor area of the window, which should look similar to this:
In this tutorial, you won’t need to look at any other files in the Supporting Files folder, so you can minimize distractions by closing
the folder in the project navigator. Again click the disclosure triangle next to the folder icon to close the Supporting Files folder.
Because you chose to use a storyboard in this project, the Info.plist file also contains the name of the storyboard file that the
application object should load. A storyboard contains an archive of the objects, transitions, and connections that define an app’s user
interface.
In the HelloWorld app, the storyboard file is named MainStoryboard.storyboard (note that the Info.plist file shows
only the first part of this name). When the app starts, MainStoryboard.storyboard is loaded and the initial view controller is
instantiated from it. A view controller is an object that manages an area of content; the initial view controller is simply the first view
controller that gets loaded when an app starts.
The HelloWorld app contains only one view controller (specifically, HelloWorldViewController). Right now,
HelloWorldViewController manages an area of content that is provided by a single view. A view is an object that draws
content in a rectangular area of the screen and handles events caused by the user’s touches. A view can also contain other views,
which are called subviews. When you add a subview to a view, the containing view is called the parent view and its subview is
called a child view. The parent view, its child views (and their child views, if any) form a view hierarchy. A view controller manages
a single view hierarchy.
Note: The views and the view controller in the HelloWorld app represent two of the three roles for app objects that are defined by the
design pattern called Model-View-Controller (MVC). The third role is the model object. In MVC, model objects represent data (such
as a to-do item in a calendar app or a shape in a drawing app), view objects know how to display the data represented by model
objects, and controller objects mediate between models and views. In the HelloWorld app, the model object is the string that holds the
name that the user enters. You don’t need to know more about MVC right now, but it’s a good idea to begin thinking about how the
objects in your app play these different roles.
In a later step, you’ll create a view hierarchy by adding three subviews to the view that’s managed by
HelloWorldViewController; these three subviews represent the text field, the label, and the button.
You can see visual representations of the view controller and its view in the storyboard.
To look at the storyboard
 Select MainStoryboard.storyboard in the project navigator.
Xcode opens the storyboard in the editor area. (The area behind the storyboard objects—that is, the area that looks like graph paper—
is called the canvas.)
When you open the default storyboard, your workspace window should look similar to this:
A storyboard contains scenes and segues. A scene represents a view controller, and a segue represents a transition between two
scenes.
Because the Single View template provides one view controller, the storyboard in your app contains one scene and no segues. The
arrow that points to the left side of the scene on the canvas is the initial scene indicator, which identifies the scene that should be
loaded first when the app starts (typically, the initial scene is the same as the initial view controller).
The scene that you see on the canvas is named Hello World View Controller because it is managed by the
HelloWorldViewController object. The Hello World View Controller scene consists of a few items that are displayed in the
Xcode outline view (which is the pane that appears between the canvas and the project navigator). Right now, the view controller
consists of the following items:
 A first responder placeholder object (represented by an orange cube).
The first responder is a dynamic placeholder that represents the object that should be the first to receive various events while the app
is running. These events include editing-focus events (such as tapping a text field to bring up the keyboard), motion events (such as
shaking the device), and action messages (such as the message a button sends when the user taps it), among others. You won’t be
doing anything with the first responder in this tutorial.
 A placeholder object named Exit for unwinding seques.
By default, when a user dismisses a child scene, the view controller for that scene unwinds (or returns) to the parent scene—that is the
scene that originally transitioned to the child scene. However, the Exit object enables a view controller to unwind to an arbitrary
scene.
 The HelloWorldViewController object (represented by a pale rectangle inside a yellow sphere).
When a storyboard loads a scene, it creates an instance of the view controller class that manages the scene.
 A view, which is listed below the view controller (to reveal this view in the outline view, you might have to open the disclosure
triangle next to Hello World View Controller).
The white background of this view is what you saw when you ran the app in Simulator.
Note: An app’s window object is not represented in the storyboard.
The area below the scene on the canvas is called the scene dock. Right now, the scene dock displays the view controller’s name (that
is, Hello World View Controller). At other times, the scene dock can contain the icons that represent the first responder, the Exit
placeholder object, and the view controller object.
Recap
In this chapter you used Xcode to create a new project based on the Single View template and you built and ran the default app that
the template defines. Then you looked at some of the basic pieces of the project, such as the main.m source file, the Info.plist
file, and the storyboard file, and learned how an app starts up. You also learned how the Model-View-Controller design pattern
defines roles for the objects in your app.
In the next chapter, you’ll learn more about the view controller and its view.
Inspecting the View Controller and Its View
As you learned earlier, a view controller is responsible for managing one scene, which represents one area of content. The content that
you see in this area is defined in the view controller’s view. In this chapter, you take a closer look at the scene managed by
HelloWorldViewController and learn how to adjust the background color of its view.
Use the Inspector to Examine the View Controller
When an app starts up, the main storyboard file is loaded and the initial view controller is instantiated. The initial view controller
manages the first scene that users see when they open the app. Because the Single View template provides only one view controller,
it’s automatically set to be the initial view controller. You can verify the status of the view controller, and find out other things about
it, by using the Xcode inspector.
To open the inspector
1.
If necessary, click MainStoryboard.storyboard in the project navigator to display the scene on the canvas.
2.
In the outline view, select Hello World View Controller (it’s listed below First Responder).
Your workspace window should look something like this:
Notice that the scene and the scene dock are both outlined in blue, and the view controller object is selected in the scene dock.
3.
4.
Click the rightmost View button in the toolbar to display the utilities area at the right side of the window (or choose View >
Utilities > Show Utilities).
Click the Attributes inspector button in the utilities area to open the Attributes inspector.
The Attributes inspector button is the fourth button from the left in the inspector selector bar at the top of the utilities area:
With the Attributes inspector open, your workspace window should look something like this (you might have to resize the window to
see everything):
In the View Controller section of the Attributes inspector, you can see that the Initial Scene option is selected:
Note that if you deselect this option, the initial scene indicator disappears from the canvas. For this tutorial, make sure the Initial
Scene option remains selected.
Change the View’s Background Color
Earlier in the tutorial, you learned that a view provides the white background that you saw when you ran the app in Simulator. To
make sure that your app is working correctly, you can set the background color of the view to something other than white and verify
that the new color is displayed by again running the app in Simulator.
Before you change the background of the view, make sure that the storyboard is still open on the canvas. (If necessary,
click MainStoryboard.storyboard in the project navigator to open the storyboard on the canvas.)
To set the background color of the view controller’s view
1.
In the outline view, click the disclosure triangle next to Hello World View Controller (if it’s not already open) and select
View.
Xcode highlights the view area on the canvas.
2.
3.
Click the Attributes button in the inspector selector bar at the top of the utilities area to open the Attributes inspector, if it’s
not already open.
In the Attributes inspector, click the white rectangle in the Background pop-up menu to open the Colors window.
The rectangle displays the current color of the item’s background. The Background pop-up menu looks like this:
Note: If instead of clicking the white rectangle, you click Default and open the pop-up menu, choose Other from the menu that
appears.
4.
In the Colors window, select a color other than white.
Your workspace window (and the Colors window) should look something like this:
Note that because Xcode highlights the view when you select it, the color on the canvas might look different from the color in the
Colors window.
5.
Close the Colors window.
Click the Run button (or choose Product > Run) to test your app in Simulator. Make sure the Scheme pop-up menu in the Xcode
toolbar still displays HelloWorld > iPhone 5.0 Simulator. You should see something like this:
Tip You don’t have to save your work before you run your app because when you click Run (or choose Product > Run), Xcode
automatically saves the files to which you’ve made changes.
Before you continue with the tutorial, restore the view’s background color to white.
To restore the view’s background color
1.
In the Attributes inspector, open the Background pop-up menu by clicking the arrows.
Note that the rectangle in the Background pop-up menu has changed to display the color you chose in the Colors window. If you click
the colored rectangle (instead of the arrows), the Colors window reopens. Because you want to reuse the view’s original background
color, it’s easier to choose it from the Background menu than it is to find it in the Colors window.
2.
3.
In the Background pop-up menu, choose the white square listed in the Recently Used Colors section of the menu.
Click the Run button to compile and run your app (and to save your changes).
After you’ve verified that your app again displays a white background, quit Simulator.
When you run your app, Xcode might open the Debug area at the bottom of the workspace window. You won’t use this pane in this
tutorial, so you can close it to make more room in your window.
To close the Debug area
 Click the Debug View button in the toolbar.
The Debug View button is the middle View button and it looks like this:
.
Recap
In this chapter, you inspected the scene and changed (and restored) the background color of the view.
In the next chapter, you add to the view the text field, label, and button that allow users to interact with your app.
Configuring the View
Xcode provides a library of objects that you can add to a storyboard file. Some of these are user interface elements that belong in a
view, such as buttons and text fields. Others are higher-level objects, such as view controllers and gesture recognizers.
The Hello World View Controller scene already contains a view. Now you need to add a button, a label, and a text field. Then, you
make connections between these elements and the view controller class so that the elements provide the behavior you want.
Add the User Interface Elements
You add user interface (UI) elements by dragging them from the object library to a view on the canvas. After the UI elements are in a
view, you can move and resize them as appropriate.
To add the UI elements to the view and lay them out appropriately
1.
2.
If necessary, select MainStoryboard.storyboard in the project navigator to display the Hello World View Controller
scene on the canvas.
If necessary, open the object library.
The object library appears at the bottom of the utilities area. If you don’t see the object library, you can click its button, which is the
third button from the left in the library selector bar:
3.
In the object library, choose Controls from the Objects pop-up menu.
Xcode displays a list of controls below the pop-up menu. The list displays each control’s name and appearance, and a short
description of its function.
4.
One at a time, drag a text field, a rounded rectangle (Round Rect) button, and a label from the list, and drop each of them
onto the view.
5.
In the view, drag the text field so that it’s near the upper-left corner of the view.
As you move the text field (or any UI element), dashed blue lines—called alignment guides—appear that help you align the item with
the center and edges of the view. Stop dragging the text field when you can see the view’s left and upper alignment guides, as shown
here:
6.
In the view, prepare to resize the text field.
You resize a UI element by dragging its resize handles, which are small white squares that can appear on the element’s borders. In
general, you reveal an element’s resize handles by selecting it on the canvas or in the outline view. In this case, the text field should
already be selected because you just stopped dragging it. If your text field looks like the one below, you’re ready to resize it; if it
doesn’t, select it on the canvas or in the outline view.
7.
Drag the text field’s right resize handle until the view’s rightmost alignment guide appears.
Stop resizing the text field when you see something like this:
8.
9.
With the text field still selected, open the Attributes inspector (if necessary).
In the Placeholder field near the top of the Text Field Attributes inspector, type the phrase Your Name.
As its name suggests, the Placeholder field provides the light gray text that helps users understand the type of information they can
enter in the text field. In the running app, the placeholder text disappears as soon as the user taps inside the text field.
10. Still in the Text Field Attributes inspector, click the middle Alignment button to center the text field’s text.
After you enter the placeholder text and change the alignment setting, the Text Field Attributes inspector should look something like
this:
11. In the view, drag the label so that it’s below the text field and its left side is aligned with the left side of the text field.
12. Drag the label’s right resize handle until the label is the same width as the text field.
A label has more resize handles than a text field. This is because you can adjust both the height and the width of a label (you can
adjust only the width of a text field). You don’t want to change the height of the label, so be sure to avoid dragging one of the resize
handles in the label’s corners. Instead, drag the resize handle that’s in the middle of the label’s right side.
13. In the Label Attributes inspector, click the middle Alignment button (to center the text you’ll display in the label).
14. Drag the button so that it’s near the bottom of the view and centered horizontally.
15. On the canvas, double-click the button and enter the text Hello.
When you double-click the button in the view (and before you enter the text), you should see something like this:
After you add the text field, label, and button UI elements and make the recommended layout changes, your project should look
similar to this:
You probably noticed that when you added the text field, label, and button to the background view, Xcode inserted items in the
outline view named Constraints. Cocoa Touch features an Auto Layout system that lets you define layout constraints for userinterface elements. Constraints represent relationships between user interface elements that affect how they alter their position and
geometry when other views are resized or when there is an orientation change. You do not change the default constraints for the views
you added to the user interface.
There are a few other changes you can make to the text field so that it behaves as users expect. First, because users will be entering
their names, you can ensure that iOS suggests capitalization for each word they type. Second, you can make sure that the keyboard
associated with the text field is configured for entering names (rather than numbers, for example) and that the keyboard displays a
Done button.
This is the principle behind these changes: Because you know at design time what type of information a text field will contain, you
can configure it so that its runtime appearance and behavior are well suited to the user’s task. You make all of these configuration
changes in the Attributes inspector.
To configure the text field
1.
2.
In the view, select the text field.
In the Text Field Attributes inspector, make the following choices:
o In the Capitalization pop-up menu, choose Words.
o Ensure that the Keyboard pop-up menu is set to Default.
o In the Return Key pop-up menu, choose Done.
After you make these choices, the Text Field Attributes inspector should look like this:
Run your app in Simulator to make sure that the UI elements you added look the way you expect them to. If you click the Hello
button, it should become highlighted, and if you click inside the text field, the keyboard should appear. At the moment, though, the
button doesn’t do anything, the label remains empty, and there’s no way to dismiss the keyboard after it appears. To add this
functionality, you need to make the appropriate connections between the UI elements and the view controller. These connections are
described next.
Note: Because you’re running the app in Simulator, and not on a device, you activate controls by clicking them instead of tapping
them.
Create an Action for the Button
When the user activates a UI element, the element can send an action message to an object that knows how to perform the
corresponding action method (such as “add this contact to the user’s list of contacts”). This interaction is part of the target-action
mechanism, which is another Cocoa Touch design pattern.
In this tutorial, when the user taps the Hello button, you want it to send a “change the greeting” message (the action) to the view
controller (the target). The view controller responds to this message by changing the string (that is, the model object) that it manages.
Then, the view controller updates the text that’s displayed in the label to reflect the change in the model object’s value.
Using Xcode, you can add an action to a UI element and set up its corresponding action method by Control-dragging from the element
on the canvas to the appropriate part of a source file (typically, a class extension in a view controller’s implementation file). The
storyboard archives the connections that you create in this way. Later, when the app loads the storyboard, the connections are
restored.
To add an action for the button
1.
2.
If necessary, select MainStoryboard.storyboard in the project navigator to display the scene on the canvas.
In the Xcode toolbar, click the Utilities button to hide the utilities area and click the Assistant Editor button to display the
assistant editor pane.
The Assistant Editor button is the middle Editor button and it looks like this:
3.
.
Make sure that the Assistant displays the view controller’s implementation file (that is,
HelloWorldViewController.m).
If it shows HelloWorldViewController.h instead, select HelloWorldViewController.m in the project navigator.
4.
On the canvas, Control-drag from the Hello button to the class extension in HelloWorldViewController.m.
A class extension in an implementation file is a place for declaring properties and methods that are private to a class. (You will learn
more about class extensions in Write Objective-C Code.) Outlets and actions should be private. The Xcode template for a view
controller includes a class extension in the implementation file; in the HelloWorld project, the class extension looks like this:
@interface HellowWorldViewController()
@end
To Control-drag, press and hold the Control key while you drag from the button to the implementation file in the assistant editor pane.
As you Control-drag, you should see something like this:
When you release the Control-drag, Xcode displays a popover in which you can configure the action connection you just made:
Note: If you release the Control-drag somewhere other than in the class extension area of HelloWorldViewController.m, you
might see a different type of popover or nothing at all. If this happens, click inside the view on the canvas to close the popover (if
necessary) and try Control-dragging again.
5.
In the popover, configure the button’s action connection:
o In the Connection pop-up menu, choose Action.
o In the Name field, enter changeGreeting: (be sure to include the colon).
In a later step, you’ll implement the changeGreeting: method so that it takes the text that the user enters into the text field and
displays it in the label.
o Make sure that the Type field contains id.
The id data type can represent any Cocoa object. You want to use id here because it doesn’t matter what type of object sends the
message.
o Make sure that the Event pop-up menu contains Touch Up Inside.
You specify the Touch Up Inside event because you want the message to be sent when the user lifts the finger inside the button.
o Make sure that the Arguments pop-up menu contains Sender.
After you configure the action connection, the popover should look like this:
6.
In the popover, click Connect.
Xcode adds a stub implementation of the new changeGreeting: method and indicates that the connection has been made by
displaying a filled-in circle to the left of the method:
When you Control-dragged from the Hello button to the class extension in HelloWorldViewController.m file and configured
the resulting action, you accomplished two things: You added, through Xcode, the appropriate code to the view controller class (in
HelloWorldViewController.m), and you created a connection between the button and the view controller. Specifically, Xcode
did the following things:
 To HelloWorldViewController.m, it added the following action method declaration to the class extension:
- (IBAction)changeGreeting:(id)sender;
 and added the following stub method to the implementation area:
- (IBAction)changeGreeting:(id)sender {
}
 Note: IBAction is a special keyword that is used to tell Xcode to treat a method as an action for target-action connections.
IBAction is defined to void.
 The sender parameter in the action method refers to the object that is sending the action message (in this tutorial, the sender is
the button).
 It created a connection between the button and the view controller.
Next, you create connections between the view controller and the two remaining UI elements (that is, the label and the text field).
Create Outlets for the Text Field and the Label
An outlet describes a connection between two objects. When you want an object (such as the view controller) to communicate with an
object that it contains (such as the text field), you designate the contained object as an outlet. When the app runs, the outlet you create
in Xcode is restored, allowing the objects to communicate with each other at runtime.
In this tutorial, you want the view controller to get the user’s text from the text field and then display the text in the label. To ensure
that the view controller can communicate with these objects, you create outlet connections between them.
The steps you take to add outlets for the text field and label are very similar to the steps you took when you added the button’s action.
Before you start, make sure that the main storyboard file is still visible on the canvas and that HelloWorldViewController.m
is still open in the assistant editor.
To add an outlet for the text field
1.
Control-drag from the text field in the view to the class extension in the implementation file.
As you Control-drag, you should see something like this:
It does not matter where you release the Control-drag as long as it’s inside the class extension. In this tutorial, the outlet declarations
for the text field and the label are shown above the method declaration for the Hello button.
2.
In the popover that appears when you release the Control-drag, configure the text field’s connection:
o Make sure that the Connection pop-up menu contains Outlet.
o In the Name field, type “textField”.
You can call the outlet whatever you want, but your code is more understandable when an outlet name bears some relationship to the
item it represents.
o Make sure that the Type field contains “UITextField”.
Setting the Type field to “UITextField” ensures that Xcode connects the outlet only to a text field.
o Make sure that the Storage pop-up menu contains Weak, which is the default value.
You will learn more about strong and weak storage later, in Acquire Foundational Programming Skills.
3.
After you make these settings, the popover should look like this:
4.
5.
In the popover, click Connect.
You accomplished two things by adding an outlet for the text field. Through this procedure:
 Xcode added appropriate code to the implementation file (HelloWorldViewController.m) of the view controller class.
Specifically, it added the following declaration to the class extension:
@property (weak, nonatomic) IBOutlet UITextField *textField;
Note: IBOutlet is a special keyword that is used only to tell Xcode to treat the object as an outlet. It’s actually defined as nothing
so it has no effect at compile time.
 Xcode established a connection from the view controller to the text field.
By establishing the connection between the view controller and the text field, the text that the user enters can be passed to the view
controller. As Xcode did with the changeGreeting: method declaration, it indicates that the connection has been made by
displaying a filled-in circle to the left of the text field declaration.
Note: Earlier versions of Xcode add an @synthesize directive in the implementation block for each property you declare using the
Control-drag approach. Because the compiler automatically synthesizes accessor methods, these directives are unnecessary. You may
safely delete them.
Now add an outlet for the label and configure the connection. Establishing a connection between the view controller and the label
allows the view controller to update the label with a string that contains the user’s text. The steps you follow for this task are the same
as the ones you followed to add the outlet for the text field, but with appropriate changes to the configuration. (Make sure that
HelloWorldViewController.m is still visible in the assistant editor.)
To add an outlet for the label
1.
2.
o
o
o
o
Control-drag from the label in the view to the class extension in HelloWorldViewController.m in the assistant
editor.
In the popover that appears when you release the Control-drag, configure the label’s connection:
Make sure that the Connection pop-up menu contains Outlet.
In the Name field, type “label”.
Make sure that the Type field contains “UILabel”.
Make sure that the Storage pop-up menu contains Weak.
3.
In the popover, click Connect.
At this point in the tutorial, you’ve created a total of three connections to your view controller:
 An action connection for the button
 An outlet connection for the text field
 An outlet connection for the label
You can verify these connections in the Connections inspector.
To open the Connections inspector for the view controller
1.
Click the Standard editor button to close the assistant editor and switch to the standard editor view.
The Standard editor button is the leftmost Editor button and it looks like this:
2.
3.
4.
Click the Utilities view button to open the utilities area.
Select Hello World View Controller in the outline view.
Show the Connections inspector in the utilities area.
The Connections inspector button is the rightmost button in the inspector selector bar, and it looks like this:
In the Connections inspector, Xcode displays the connections for the selected object (in this case, the view controller). In your
workspace window, you should see something like this:
You’ll see a connection between the view controller and its view, in addition to the three connections you created. Xcode provides
this default connection between the view controller and its view; you do not have to access it in any way.
Make the Text Field’s Delegate Connection
You have one more connection to make in your app: You need to connect the text field to an object that you specify as its delegate. In
this tutorial, you use the view controller for the text field’s delegate.
You need to specify a delegate object for the text field. This is because the text field sends a message to its delegate when the user
taps the Done button in the keyboard (recall that a delegate is an object that acts on the behalf of another object). In a later step, you’ll
use the method associated with this message to dismiss the keyboard.
Make sure that the storyboard file is open on the canvas. If it’s not, select MainStoryboard.storyboard in the project
navigator.
To set the text field’s delegate
1.
In the view, Control-drag from the text field to the yellow sphere in the scene dock (the yellow sphere represents the view
controller object).
When you release the Control-drag, you should see something like this:
2.
Select delegate in the Outlets section of the translucent panel that appears.
Prepare the App for Accessibility
The iOS operating system provides a host of features that help make apps accessible to all users, including those with visual, auditory,
and physical disabilities. By making your app accessible, you open it up to millions of people who would otherwise not be able to use
it.
A major accessibility feature is VoiceOver, Apple’s innovate screen-reading technology. With VoiceOver, users can navigate and
control the parts of an app without having to see the screen. By touching a control or other object in the user interface, users can learn
where they are, what they can do, and what will happen if they do something.
You can add several accessibility attributes to any view in your user interface. These attributes include the current value of the view
(such as the text in a text field), its label, a hint, and a number of traits. For the HelloWorld app, you are going to add a hint to the text
field.
Note: Any accessibility text that you add should be localized. To learn how to do this, see Internationalize Your App in App Design.
To add an accessibility hint
1.
2.
3.
Select the storyboard file (base internationalization) in the project navigator.
Select the text field.
In the Accessibility section of the Identity inspector, type “Type your name” in the Hint field.
Test the App
Click Run to test your app. You should find that the Hello button becomes highlighted when you click it. You should also find that if
you click in the text field, the keyboard appears and you can enter text. However, there’s still no way to dismiss the keyboard. To do
that, you have to implement the relevant delegate method. You’ll do that in the next chapter. For now, quit Simulator.
Recap
When you created the appropriate connections between the view controller on the canvas and the class extension in the
implementation file (that is, HelloWorldViewController.m) in the assistant editor, you also updated the implementation file
to support the outlets and the action.
You don’t have to use the Xcode feature that automatically adds code when you establish a connection by Control-dragging from the
canvas to a source file. Instead, you can write the property and method declarations in the class extension or (for public properties and
methods) the header file yourself, and then make the connections as you did with the text field’s delegate. Typically, though, you
make fewer mistakes (and have less typing to do) when you let Xcode do as much of the work as it can.
Implementing the View Controller
There are several parts to implementing the view controller: You need to add a property for the user’s name, implement the
changeGreeting: method, and ensure that the keyboard is dismissed when the user taps Done.
Add a Property for the User’s Name
You need to add a property declaration for the string that holds the user’s name, so that your code always has a reference to it.
Because this property should be public—that is, visible to clients and subclasses—you add this declaration to the view controller’s
header file, HelloWorldViewController.h. Public properties indicate how you intend objects of your class to be used.
A property declaration is a directive that tells the compiler how to generate the accessor methods for a variable, such as the variable
used to hold the user’s name. (You’ll learn about accessor methods after you add the property declaration.)
At this point in the tutorial, you don’t need to make any further changes to the storyboard file. To give yourself more room in which to
add the code described in the following steps, hide the utilities area by clicking the Utilities View button again (or by choosing View
> Utilities > Hide Utilities).
To add a property declaration for the user’s name
1.
2.
In the project navigator, select HelloWorldViewController.h.
Before the @end statement, write an @property statement for the string.
The property declaration should look like this:
@property (copy, nonatomic) NSString *userName;
You can copy and paste the code above or you can type it into the editor pane. If you decide to type the code, notice that Xcode
suggests completions to what you’re typing. For example, as you begin to type @prop... Xcode guesses that you want to enter
@property, so it displays this symbol in an inline suggestion panel that looks similar to this:
If the suggestion is appropriate (as it is in the example shown above), press Return to accept it.
As you continue to type, Xcode might offer a list of suggestions from which you can choose. For example, Xcode might display the
following list of completions as you type NSStr...:
When Xcode displays a completion list, press Return to accept the highlighted suggestion. If the highlighted suggestion isn’t correct
(as is the case in the list shown above), use the arrow keys to select the appropriate item in the list.
The compiler automatically synthesizes accessor methods for any property you declare. An accessor method is a method that gets or
sets the value of an object’s property (sometimes, accessor methods are also called “getters” and “setters”). For example, the compiler
generates declarations of the following getter and setter for the userName property you just declared, along with their
implementations:
 - (NSString *)userName;
 - (void)setUserName:(NSString *)newUserName;
The compiler also automatically declares private instance variables to back each declared property. For example, it declares an
instance variable named _userName that backs the userName property.
Note: The compiler adds the accessor methods that it generates to the compiled code; it does not add them to your source code.
Implement the changeGreeting: Method
In the previous chapter, “Configuring the View,” you configured the Hello button so that when the user taps it, it sends a
changeGreeting: message to the view controller. In response, you want the view controller to display in the label the text that the
user entered in the text field. Specifically, the changeGreeting: method should:
 Retrieve the string from the text field and set the view controller’s userName property to this string.
 Create a new string that is based on the userName property and display it in the label.
To implement the changeGreeting: method
1.
If necessary, select HelloWorldViewController.m in the project navigator.
You might have to scroll to the end of the file to see the changeGreeting: stub implementation that Xcode added for you.
2.
Complete the stub implementation of the changeGreeting: method by adding the following code:
- (IBAction)changeGreeting:(id)sender {
self.userName = self.textField.text;
NSString *nameString = self.userName;
if ([nameString length] == 0) {
nameString = @"World";
}
NSString *greeting = [[NSString alloc] initWithFormat:@"Hello, %@!",
nameString];
self.label.text = greeting;
}
There are several interesting things to note in the changeGreeting: method:
 self.userName = self.textField.text; retrieves the text from the text field and sets the view controller’s
userName property to the result.
In this tutorial, you don’t actually use the string that holds the user’s name anywhere else, but it’s important to remember its role: It’s
the very simple model object that the view controller is managing. In general, the controller should maintain information about app
data in its own model objects—app data shouldn’t be stored in user interface elements such as the text field of the HelloWorld app.
 NSString *nameString = self.userName; creates a new variable (of type NSString) and sets it to the view
controller’s userName property.
 @"World" is a string constant represented by an instance of NSString. If the user runs your app but does not enter any text
(that is, [nameString length] == 0), nameString will contain the string “World”.
 The initWithFormat: method is supplied for you by the Foundation framework. It creates a new string that follows the
format specified by the format string you supply (much like the printf function of the ANSI C library).
In the format string, %@ acts as a placeholder for a string object. All other characters within the double quotation marks of this format
string will be displayed onscreen exactly as they appear.
Configure the View Controller as the Text Field’s Delegate
If you build and run the app, you should find that when you click the button, the label shows “Hello, World!” If you select the text
field and start typing on the keyboard, though, you should find that you still have no way to dismiss the keyboard when you’re
finished entering text.
In an iOS app, the keyboard is shown automatically when an element that allows text entry becomes the first responder; it is dismissed
automatically when the element loses first responder status. (Recall that the first responder is the object that first receives notice of
various events, such as tapping a text field to bring up the keyboard.) Although there’s no way to directly send a message to the
keyboard from your app, you can make it appear or disappear as a side effect of toggling the first responder status of a text-entry UI
element.
The UITextFieldDelegate protocol is defined by the UIKit framework, and it includes the textFieldShouldReturn:
method that the text field calls when the user taps the Return button (regardless of the actual title of this button). Because you set the
view controller as the text field’s delegate (in “To set the text field’s delegate”), you can implement this method to force the text field
to lose first responder status by sending it the resignFirstResponder message—which has the side effect of dismissing the
keyboard.
Note: A protocol is basically just a list of methods. If a class conforms to (or adopts) a protocol, it guarantees that it implements the
required methods of a protocol. (Protocols can also include optional methods.) A delegate protocol specifies all the messages an
object might send to its delegate.
To configure HelloWorldViewController as the text field’s delegate
1.
2.
If necessary, select HelloWorldViewController.m in the project navigator.
Implement the textFieldShouldReturn: method.
The method should tell the text field to resign first responder status. The implementation should look something like this:
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
if (theTextField == self.textField) {
[theTextField resignFirstResponder];
}
return YES;
}
In this app, it’s not really necessary to test the theTextField == self.textField expression because there’s only one text
field. This is a good pattern to use, though, because there may be occasions when your object is the delegate of more than one object
of the same type and you might need to differentiate between them.
3.
4.
Select HelloWorldViewController.h in the project navigator.
To the end of the @interface line, add <UITextFieldDelegate>.
Your interface declaration should look like this:
@interface HelloWorldViewController : UIViewController <UITextFieldDelegate>
...
This declaration specifies that your HelloWorldViewController class adopts the UITextFieldDelegate protocol.
Test the App
Build and run the app. This time, everything should behave as you expect. In Simulator, click Done to dismiss the keyboard after you
have entered your name, and then click the Hello button to display “Hello, Your Name!” in the label.
If the app doesn’t behave as you expect, you need to troubleshoot. For some areas to investigate, see “Troubleshooting and Reviewing
Code”.
Recap
Now that you’ve finished the implementation of the view controller, you’ve completed your first iOS app. Congratulations!
Return to Start Developing iOS Apps Today to continue learning about iOS app development. If you had trouble getting your app to
work correctly, try the problem-solving approaches described in the next chapter before returning to Start Developing iOS Apps
Today.
Troubleshooting and Reviewing the Code
If you are having trouble getting your app to work correctly, try the problem-solving approaches described in this chapter. If your app
still isn’t working as it should, compare your code with the listings shown at the end of this chapter.
Code and Compiler Warnings
Your code should compile without any warnings. If you do receive warnings, it’s recommended that you treat them as very likely to
be errors. Because Objective-C is a very flexible language, sometimes the most you get from the compiler is a warning.
Check the Storyboard File
As a developer, if things don’t work correctly, your natural instinct is probably to check your source code for bugs. But when you use
Cocoa Touch, another dimension is added. Much of your app’s configuration may be “encoded” in the storyboard. For example, if
you haven’t made the correct connections, your app won’t behave as you expect.
 If the text doesn’t update when you click the button, it might be that you didn’t connect the button’s action to the view
controller, or that you didn’t connect the view controller’s outlets to the text field or label.
 If the keyboard does not disappear when you click Done, you might not have connected the text field’s delegate or connected
the view controller’s textField outlet to the text field. Be sure to check the text field’s connections on the storyboard:
Control-click the text field to reveal the translucent connections panel. You should see filled-in circles next to the delegate
outlet and the textField referencing outlet.
If you have connected the delegate, there might be a more subtle problem (see the next section, “Delegate Method Names”).
Delegate Method Names
A common mistake with delegates is to misspell the delegate method name. Even if you’ve set the delegate object correctly, if the
delegate doesn’t use the right name in its method implementation, the correct method won’t be invoked. It’s usually best to copy and
paste delegate method declarations, such as textFieldShouldReturn:, from the documentation.
Code Listings
This section provides listings for the interface and implementation files of the HelloWorldViewController class. Note that the
listings don’t show comments and other method implementations that are provided by the Xcode template.
The Interface file: HelloWorldViewController.h
#import <UIKit/UIKit.h>
@interface HelloWorldViewController : UIViewController <UITextFieldDelegate>
@property (copy, nonatomic) NSString *userName;
@end
The Implementation File: HelloWorldViewController.m
#import "HelloWorldViewController.h"
@interface HelloWorldViewController ()
@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet UILabel *label;
- (IBAction)changeGreeting:(id)sender;
@end
@implementation HelloWorldViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)changeGreeting:(id)sender {
self.userName = self.textField.text;
NSString *nameString = self.userName;
if ([nameString length] == 0) {
nameString = @"World";
}
NSString *greeting = [[NSString alloc] initWithFormat:@"Hello, %@!", nameString];
self.label.text = greeting;
}
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
if (theTextField == self.textField) {
[theTextField resignFirstResponder];
}
return YES;
}
@end
Manage Your Workflow in Xcode
As you saw in the tutorial Your First iOS App, you perform your major workflow tasks in the Xcode workspace window. A separate
Organizer window allows you to perform ancillary tasks, such as reading documentation, enabling devices for testing, and preparing
your app for submission to the App Store.
The workspace window features a navigator area, an editor area, and a utility area. In Your First iOS App, you used the navigator area
to select files to edit. You used the editor area to edit source files and to design user interface components. In the utility area, you set
label text and a button title.
Customize Your Workspace
You can hide the navigator, editor, and utility areas in various combinations. In Your First iOS App, you used the View selector in the
toolbar to hide and disclose the utility area. Hiding the utility area allowed you to view a larger editor area, whereas disclosing the
utility area allowed you to inspect and select various object attributes.
You can customize the workspace in other ways, such as by using Safari-style tabs to implement multiple, workflow-specific layouts
of the workspace window. For example, you can use one tab to view a header file and another to view an implementation file.
To view source code files in tabs
1.
2.
3.
4.
5.
6.
7.
Select HelloWorldViewController.h in the project navigator to display the header file in the source editor.
Choose View > Show Tab Bar.
Choose File > New > Tab.
Select HelloWorldViewController.m in the project editor to display the implementation file in the tabbed source editor
window.
Click the tabs to move between source files.
To remove a tab, move the pointer to the tab and click its close box.
You can hide the tab bar by choosing View > Hide Tab Bar.
You can also create multiple workspace windows. Each tab or workspace window can be customized independently of the others.
To view source code files in multiple windows
1.
2.
3.
4.
Select HelloWorldViewController.h in the project navigator to display the header file in the source editor.
Choose File > New > Window to open a new workspace window.
Select HelloWorldViewController.m in the project editor to display the implementation file in the new window.
Customize either window, such as by showing and hiding the utilities area with the View selector.
Test Your App in iOS Simulator
When you run your app to test or debug it, you can run it in iOS Simulator on your Mac. Using iOS Simulator, you can make sure
your app behaves the way you want.
The debugging environment is built into Xcode. When your app is running, the debug navigator shows a stack trace that you can
expand or compress to show or hide stack frames as you debug. As you step through, you can lock onto a single thread and follow that
specific thread of execution.
To run your app in the Xcode debugger
1.
2.
3.
In your HelloWorld project, select HelloWorldViewController.m in the project navigator to display the file in the source
editor.
Locate the statement self.label.text = greeting;}.
Click the gutter to the left of this statement to insert a breakpoint.
A blue breakpoint indicator appears.
4.
5.
6.
Click the Run button in the toolbar to build and run HelloWorld in iOS Simulator.
Type World into the text field, and click the Done button to close the keyboard.
Click the Hello button.
The breakpoint causes the execution of HelloWorld to stop. The workspace window moves to the foreground with the debug
area open at the bottom of the editor area. The debug area displays the local variables and their current values. To remove the
breakpoint, click and drag it away from the gutter.
Test Your App on an iOS Device
Although you can test your app’s basic behavior in iOS Simulator, you should also run it on devices connected to your Mac. Devices
provide the ultimate testing environments, in which you can observe your app as it will behave on your customers’ devices. Such
testing is necessary because iOS Simulator doesn’t run all threads that run on devices. Ideally, you should test the app on all of the
devices and iOS versions that you intend to support.
If you joined the iOS Developer Program, you can use Xcode right now to start running, testing, and debugging your app on a device.
(Set Up earlier in this road map contained information about enrolling as an iOS Developer.)
To run your app on a device, you must obtain an development certificate from Apple. Your app must be cryptographically signed
before it can run on a device, and this certificate is used to sign your app. You obtain this certificate through the Xcode Organizer
window.
Note: If you are reading the following instructions in the Xcode document organizer, Control-click anywhere on this page and select
Open Page in Browser from the contextual menu. This page appears in your default web browser. After you select the Devices
organizer in the following steps, the Devices organizer replaces this page in the documentation organizer, so having the instructions in
a web browser will be helpful. When you have finished these instructions, click Documentation in the toolbar of the Organizer
window if you want to resume reading this page in Xcode.
To obtain your development certificate in Xcode
1.
2.
3.
4.
5.
Choose Window > Organizer.
Click Devices.
Select Provisioning Profiles under Library.
Click the Refresh button at the bottom of the window.
Enter your Apple Developer user name and password, and click Log in.
After you log in to your account, a prompt appears asking whether Xcode should request your development certificate.
6.
Click the Submit Request button.
The development certificate is added to your keychain and later added to the iOS Team Provisioning Profile. Another prompt
may appear asking whether Xcode should request your distribution certificate, which is needed later for submitting your app
to the App Store. If appropriate, click the Submit Request button again.
To run an app on a device, you must also install an associated provisioning profile on the device. This provisioning profile enables
your app to run by identifying you (through your development certificate) and your device (by listing its unique device identifier).
To provision your device in Xcode
1.
2.
3.
4.
Connect your device to your Mac.
Open the Devices Organizer.
Select your device under Devices.
Click the "Use for Development" button.
The first time you add a device ID to your account, Xcode creates the iOS Team Provisioning Profile using the Xcode
wildcard app ID, your development certificate, and the device ID. The iOS Team Provisioning Profile is also installed on
your device.
With a development certificate and a provisioning profile in place, you can run your app on an installed device. You can also use the
Xcode debugging and performance profiling facilities while your app runs on the device.
To launch your app on a connected device
1.
2.
In the Xcode workspace window for your project, choose Product > Edit Scheme to open the scheme editor.
Select your device from the Destination pop-up menu.
When you plug a device with a valid provisioning profile into your Mac, its name and the iOS release it’s running appear as
an item in the Destination pop-up menu.
3.
4.
Click OK to close the scheme editor.
Click the Run button.
If a prompt appears asking whether the codesign tool can sign the app using a key in your keychain, click Allow or Always
Allow.
Find Xcode Help Quickly
During the course of app development, you perform a lot of operations in Xcode. If you need assistance with a task, Xcode provides
workflow-sensitive help, which you can access directly from the Xcode user interface. This assistance includes easy-to-follow steps,
videos or screenshots, and concise descriptions that help you get back to work quickly.
To view Xcode help
1.
2.
In your HelloWorld project, select HelloWorldViewController.h in the project navigator to display the header file in the
source editor.
If you are reading this document in the Xcode document organizer, locate its Go Back button. You will need to click it to
return this document after performing the remaining steps.
3.
Control-click anywhere in the source editor.
A contextual menu opens in which Source Editor Help is the final item.
4.
Choose Source Editor Help to display a list of common source editor tasks.
5.
6.
Choose Source Editor Help > “Catching Mistakes with Fix-it” to see a help article in the Documentation organizer.
Click the thumbnail image to play an instructional video.
Improve the Performance of Your App
To ensure that you deliver the best user experience for your software, launch Instruments from Xcode to analyze the performance of
your app as it runs in iOS Simulator or on a device. Instruments gathers data from your running app and presents it in a graphical
timeline.
You can gather data about your app’s memory usage, disk activity, network activity, and graphics performance, among other
measurements. By viewing the data together, you can analyze different aspects of your app’s performance to identify potential areas
of improvement. You can automate the testing of your app’s user interface elements. You can also compare your app’s behavior at
different times to determine whether your changes improve the performance of your app.
To begin analyzing the performance of your app
1.
2.
3.
From your HelloWorld project in Xcode, choose Product > Perform Action > Profile Without Building.
Under iOS Simulator in the left column, click All to see the available trace templates.
Select the Leaks template and click Profile.
The Instruments app launches along with the iOS Simulator running HelloWorld.
4.
5.
6.
Type your name into the HelloWorld text field, click the Done button to close the keyboard, and click Hello.
Choose iOS Simulator > Quit iOS Simulator to stop recording performance data.
Click Allocations in the Instruments pane to examine the HelloWorld project's memory allocations.
For example, the track pane graphs where the memory allocations occurred, allowing you to see how frequently memory
allocations occurred throughout the program. (Large spikes in the track pane can indicate potential bottlenecks that you
might want to mitigate either by preallocating some blocks or by being more lazy about other blocks.)
Manage Versions of Your App
If something goes wrong because of a code change you make, an Xcode snapshot makes it easy to restore your project, even a deleted
project, to a previous state. A snapshot saves the current state of your project onto disk for possible restoration later. The Projects
organizer in Xcode lists your snapshots.
You can create a snapshot manually whenever you like, and you can set Xcode to automatically create snapshots in other
circumstances, such as before every build or before executing every Find and Replace operation.
To create and restore a snapshot of your project
1.
2.
3.
4.
5.
With the HelloWorld project open, choose File > Create Snapshot.
Type a name and description in the provided fields.
Click Create Snapshot.
To view the snapshot, Choose Window > Organizer to display the Organizer window.
Click the Projects button.
You should see a list of all snapshots.
Source control management (SCM) allows you to keep track of changes at a more fine-grained level than snapshots allow. (Source
control management also helps you coordinate efforts if you work with a team of programmers.) An SCM system saves multiple
versions of each file onto disk, storing metadata about each version of each file in an SCM repository.
Xcode supports two popular SCM systems: Git and Subversion. Xcode includes a version editor that makes it easy to compare
versions of files saved in repositories from either system. If you find you’ve introduced bugs in your code, you can compare changes
between the latest version of a file and an earlier version that worked correctly, helping you to zero in on the source of the trouble.
Distribute and Publish Your App
Xcode makes it easy to share your app with testers before release and to publish your app on the App Store. You start the distribution
process by using the scheme editor to create an archive of your app in Xcode. You can then use the Archives organizer in Xcode to
share your app with others for testing.
When you’re ready to publish your app, use the Archives organizer to perform essential validation tests required for App Store
publication. Passing these tests ensures that your app’s approval process is as fast as possible. You'll then be ready to submit your app
directly to the App Store from Xcode.
You’ll learn more about distributing and publishing your app in the article Prepare for App Store Submission later in this road map.
Write Objective-C Code
If you haven’t programmed for either iOS or Mac OS X, you need to become acquainted with the primary programming language,
Objective-C. Objective-C is a not a difficult language, and once you spend some time with it, you’ll appreciate its elegance. The
Objective-C language enables sophisticated object-oriented programming. It extends the standard ANSI C programming language by
providing a syntax for defining classes and methods. It also promotes dynamic extension of classes and interfaces that any class can
adopt.
If you are familiar with ANSI C, the following information should help you learn the basic syntax of Objective-C. And if you have
programmed with other object-oriented languages, you’ll find that many of the traditional object-oriented concepts, such as
encapsulation, inheritance, and polymorphism, are all present in Objective-C. If you are not familiar with ANSI C, it’s a good idea to
at least read an overview of the C language before you attempt to read this article.
The Objective-C language is fully explained in The Objective-C Programming Language.
Objective-C Is a Superset of the C Language
The Objective-C language specifies a syntax for defining classes and methods, for calling methods of objects, and for dynamically
extending classes and creating programming interfaces adapted to address specific problems. As a superset of the C programming
language, Objective-C supports the same basic syntax as C. You get all of the familiar elements, such as primitive types (int,
float, and so on), structures, functions, pointers, and control-flow constructs such as if...else and for statements. You also
have access to the standard C library routines, such as those declared in stdlib.h and stdio.h.
Objective-C adds the following syntax and features to ANSI C:
 Definition of new classes
 Class and instance methods
 Method invocation (called messaging)




Declaration of properties (and automatic synthesizing of accessor methods from them)
Static and dynamic typing
Blocks—encapsulated segments of code that can be executed at any time
Extensions to the base language such as protocols and categories
Don’t worry if these aspects of Objective-C are unfamiliar to you now. As you progress through the remainder of this article, you will
learn about them. If you’re a procedural programmer new to object-oriented concepts, it might help at first to think of an object as
essentially a structure with functions associated with it. This notion is not too far off the reality, particularly in terms of runtime
implementation.
In addition to providing most of the abstractions and mechanisms found in other object-oriented languages, Objective-C is a very
dynamic language, and that dynamism is its greatest advantage. It is dynamic in that it permits an app’s behavior to be determined
when it is running (that is, at runtime) rather than being fixed when the app is built. Thus the dynamism of Objective-C frees a
program from constraints imposed when it’s compiled and linked; instead it shifts much of the responsibility for symbol resolution to
runtime, when the user is in control.
Classes and Objects
As in most other object-oriented languages, classes in Objective-C support the encapsulation of data and define the actions that
operate on that data. An object is a runtime instance of a class. It contains its own in-memory copy of the instance variables declared
by its class and pointers to the methods of the class. You create an object in a two-step procedure called allocation and initialization.
The specification of a class in Objective-C requires two distinct pieces: the interface and the implementation. The interface portion
contains the class declaration and defines the public interface of the class. As with C code, you define header files and source files to
separate public declarations from the implementation details of your code. (You can put other declarations in your implementation file
if they are part of the programmatic interfaces but are meant to be private.) These files have the filename extensions listed in the
following table.
Extension
Source type
.h
Header files. Header files contain class, type, function, and constant declarations.
.m
Implementation files. A file with this extension can contain both Objective-C and C code. It is sometimes called a source
file.
.mm
Implementation files. An implementation file with this extension can contain C++ code in addition to Objective-C and C
code. Use this extension only if you actually refer to C++ classes or features from your Objective-C code.
When you want to include header files in your source code, specify a pound import (#import) directive as one of the first lines in a
header or source file; a #import directive is like C’s #include directive, except that it makes sure that the same file is never
included more than once. If you want to import most or all of the header files of a framework, import the framework’s umbrella
header file, which has the same name as the framework. The syntax for importing the header files of the (hypothetical) Gizmo
framework is:
#import <Gizmo/Gizmo.h>
The diagram below shows the syntax for declaring a class called MyClass, which inherits from the base (or root) class, NSObject.
(A root class is one that all other classes directly or indirectly inherit from.) The class declaration begins with the @interface
compiler directive and ends with the @end directive. Following the class name (and separated from it by a colon) is the name of the
parent class. In Objective-C, a class can have only one parent.
You write declarations of properties and methods between the @interface and @end directives. These declarations form the
public interface of the class. (Declared properties are described in “Declared Properties and Accessor Methods.”) A semicolon marks
the end of each property and method declaration. If the class has custom functions, constants, or data types associated with its public
interface, put their declarations outside the @interface . . . @end block.
The syntax for a class implementation is similar. It begins with an @implementation compiler directive (followed by the name of
the class) and ends with an @end directive. Method implementations go in between. (Function implementations should go outside the
@implementation . . . @end block.) An implementation should always import its interface file as one of the first lines of code.
#import "MyClass.h"
@implementation MyClass
- (id)initWithString:(NSString *)aName
{
// code goes here
}
+ (MyClass *)myClassWithString:(NSString *)aName
{
// code goes here
}
@end
Objective-C supports dynamic typing for variables containing objects, but it also supports static typing. Statically typed variables
include the class name in the variable type declaration. Dynamically typed variables use the type id for the object instead. You find
dynamically typed variables used in certain situations. For example, a collection object such as an array (where the exact types of the
contained objects may be unknown) might use dynamically typed variables. Such variables provide tremendous flexibility and allow
for greater dynamism in Objective-C programs.
This example shows statically and dynamically typed variable declarations:
MyClass *myObject1;
id
myObject2;
NSString *userName;
// Static typing
// Dynamic typing
// From Your First iOS App (static typing)
Notice the asterisk (*) in the first declaration. In Objective-C, object references must always be pointers. If this requirement doesn’t
make complete sense to you, don’t worry. You don’t have to be an expert with pointers to be able to start programming with
Objective-C. You just have to remember to put an asterisk in front of the variable names for statically typed object declarations. The
id type implies a pointer.
Methods and Messaging
If you’re new to object-oriented programming, it might help to think of a method as a function that is scoped to a specific object. By
sending a message to—or messaging—an object, you call a method of that object. There are two kinds of methods in Objective-C:
instance methods and class methods.
 An instance method is a method whose execution is scoped to a particular instance of the class. In other words, before you call
an instance method, you must first create an instance of the class. Instance methods are the most common type of method.
 A class method is a method whose execution is scoped to the method’s class. It does not require an instance of an object to be
the receiver of a message.
The declaration of a method consists of the method type identifier, a return type, one or more signature keywords, and the parameter
type and name information. Here’s the declaration of the insertObject:atIndex: instance method.
For instance methods, the declaration is preceded by a minus sign (-); for class methods, the corresponding indicator is a plus sign
(+). “Class Methods,” below, describes class methods in greater detail.
A method’s actual name (insertObject:atIndex:) is a concatenation of all of the signature keywords, including colon
characters. The colon characters declare the presence of a parameter. In the above example, the method takes two parameters. If a
method has no parameters, you omit the colon after the first (and only) signature keyword.
When you want to call a method, you do so by sending a message to the object that implements the method. (Although the phrase
"sending a message” is commonly used as a synonym for “calling a method,” the Objective-C runtime does the actual sending.) A
message is the method name along with the parameter information the method needs (properly conforming to type). All messages you
send to an object are dispatched dynamically, thus facilitating the polymorphic behavior of Objective-C classes. (Polymorphism refers
to the ability of different types of objects to respond to the same message.) Sometimes the method invoked is implemented by a
superclass of the class of the object receiving the message.
To dispatch a message, the runtime requires a message expression. A message expression encloses with brackets ([ and ]) the
message itself (along with any required parameters) and, just inside the leftmost bracket, the object receiving the message. For
example, to send the insertObject:atIndex: message to an object held by the myArray variable, you would use the
following syntax:
[myArray insertObject:anObject atIndex:0];
To avoid declaring numerous local variables to store temporary results, Objective-C lets you nest message expressions. The return
value from each nested expression is used as a parameter, or as the receiving object, of another message. For example, you could
replace any of the variables used in the previous example with messages to retrieve the values. Thus, if you had another object called
myAppObject that had methods for accessing the array object and the object to insert into the array, you could write the preceding
example to look something like the following:
[[myAppObject theArray] insertObject:[myAppObject objectToInsert] atIndex:0];
Objective-C also provides a dot-notation syntax for invoking accessor methods. Accessor methods get and set the state of an object,
and thus are key to encapsulation, which is an important feature of all objects. Objects hide, or encapsulate, their state and present an
interface common to all instances for accessing that state. Using dot-notation syntax, you could rewrite the previous example like this:
[myAppObject.theArray insertObject:myAppObject.objectToInsert atIndex:0];
You can also use dot-notation syntax for assignment:
myAppObject.theArray = aNewArray;
This syntax is simply a different way to write [myAppObject setTheArray:aNewArray];. You cannot use a reference to a
dynamically typed object (object of type id) in a dot-notation expression.
You have used dot syntax already for assigning to a variable in Your First iOS App:
self.userName = self.textField.text;
Class Methods
Although the preceding examples sent messages to an instance of a class, you can also send messages to the class itself. (A class is an
object of type Class created by the runtime.) When messaging a class, the method you specify must be defined as a class method
instead of an instance method. Class methods are a feature similar to static class methods in C++.
You often use class methods either as factory methods to create new instances of the class or to access some piece of shared
information associated with the class. The syntax for a class method declaration is identical to that of an instance method except that
you use a plus (+) sign instead of a minus sign for the method type identifier.
The following example illustrates how you use a class method as a factory method for a class. In this case, the array method is a
class method on the NSArray class—and inherited by NSMutableArray—that allocates and initializes a new instance of the class
and returns it to your code.
NSMutableArray *myArray = nil;
// nil is essentially the same as NULL
// Create a new array and assign it to the myArray variable.
myArray = [NSMutableArray array];
Declared Properties and Accessor Methods
A property in the general sense is some data encapsulated or stored by an object. It is either an attribute—such as a name or a color—
or a relationship to one or more other objects. The class of an object defines an interface that enables users of its objects to get and set
the values of encapsulated properties. The methods that perform these actions are called accessor methods.
There are two types of accessor methods, and each method must conform to a naming convention. A “getter” accessor method, which
returns the value of a property, has the same name as the property. A "setter” accessor method, which sets a new value for a property,
has the form setPropertyName:, where the first letter of the property name is capitalized. Properly named accessor methods are a
critical element of several technologies of the Cocoa and Cocoa Touch frameworks, including key-value coding (KVC), which is a
mechanism for accessing an object’s properties indirectly through their names.
Objective-C offers declared properties as a notational convenience for the declaration and implementation of accessor methods. In
Your First iOS App you declared the userName property:
@property (nonatomic, copy) NSString *userName;
Declared properties eliminate the need to implement a getter and setter method for each property exposed in the class. Instead, you
specify the behavior you want using the property declaration. The compiler can then create—or synthesize—actual getter and setter
methods based on that declaration. Declared properties reduce the amount of boilerplate code you have to write and, as a result, make
your code much cleaner and less error prone. Use declared properties or accessor methods to get and set items of an object’s state.
You include property declarations with the method declarations in your class interface. You declare public properties in the class
header files; you declare private properties in a class extension in the source file. (See “Protocols and Categories” for a short
description of class extensions along with an example.) Properties of controller objects such as delegates and view controllers should
typically be private.
The basic declaration for a property uses the @property compiler directive, followed by the type information and name of the
property. You can also configure the property with custom options, which define how the accessor methods behave, whether the
property is a weak reference, and whether it is read-only. The options are in parentheses following the @property directive.
The following lines of code illustrate a few more property declarations:
@property (copy) MyModelObject *theObject;
@property (readonly) NSView *rootView;
@property (weak) id delegate;
// Copy the object during assignment.
// Declare only a getter method.
// Declare delegate as a weak reference
The compiler automatically synthesizes declared properties. In synthesizing a property, it creates accessor methods for it as well as a
private instance variable that “backs” the property. The instance variable has the same name as the property but with an underscore
prefix (_). Your app should directly access an instance variable (instead of its property) only in methods for object initialization and
deallocation.
If you want a different name for an instance variable, you can bypass autosynthesis and explicitly synthesize a property. Use the
@synthesize compiler directive in the class implementation to ask the compiler to generate the accessor methods along with the
specially named instance variable. For example:
@synthesize enabled = _isEnabled;
Incidentally, when you declare a property you can specify custom names for the accessor methods, typically to make the getter
methods of Boolean properties follow a conventional form, as shown here:
@property (assign, getter=isEnabled) BOOL enabled; // Assign new value, change name of
getter method
Blocks
Blocks are objects that encapsulate a unit of work—that is, a segment of code—that can be executed at any time. They are essentially
portable and anonymous functions that one can pass in as parameters of methods and functions or that can be returned from methods
and functions. Blocks themselves have a typed parameter list and may have an inferred or a declared return type. You can also assign
a block to a variable and then call it just as you would a function.
A caret (^) is used as a syntactic marker for blocks. There are other, familiar syntactic conventions for parameters, return values, and
body of the block (that is, the executed code). The following figure explains the syntax, specifically when assigning a block to a
variable.
You can then call the block variable as if it were a function:
int result = myBlock(4); // result is 28
A block shares data in the local lexical scope. This characteristic of blocks is useful because if you implement a method and that
method defines a block, the block has access to the local variables and parameters of the method (including stack variables) as well as
to functions and global variables, including instance variables. This access is read-only, but if a variable is declared with the
__block modifier, its value can be changed within the block. Even after the method or function enclosing a block has returned and
its local scope has been destroyed, the local variables persist as part of the block object as long as there is a reference to the block.
As method or function parameters, blocks can serve as a callback. When invoked, the method or function performs some work and, at
the appropriate moments, calls back to the invoking code—via the block—to request additional information or to obtain programspecific behavior from it. Blocks enable the caller to provide the callback code at the point of invocation. Instead of packaging the
required data in a “context” structure, blocks capture data from the same lexical scope as does the host method or function. Because
the block code does not have to be implemented in a separate method or function, your implementation code can be simpler and easier
to understand.
Objective-C frameworks have many methods with block parameters. For example, the NSNotificationCenter class of the
Foundation framework declares the following method, which has a block parameter:
- (id)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue
usingBlock:(void (^)(NSNotification *note))block
This method adds an observer to the notification center (notifications are discussed in Streamline Your App with Design Patterns).
When a notification of the specified name is posted, the block is invoked to handle the notification.
opQ = [[NSOperationQueue alloc] init];
[[NSNotificationCenter defaultCenter] addObserverForName:@"CustomOperationCompleted"
object:nil queue:opQ
usingBlock:^(NSNotification *notif) {
// handle the notification
}];
Protocols and Categories
A protocol declares methods that can be implemented by any class, even if those classes implementing the protocol don’t have a
common superclass. Protocol methods define behavior that is independent of any particular class. Protocols simply define an interface
that other classes are responsible for implementing. When your class implements the methods of a protocol, your class is said to
conform to that protocol.
From a practical perspective, a protocol defines a list of methods that establishes a contract between objects without requiring them to
be instances of any specific class. This contract enables communication between those objects. One object wants to tell another object
about the events it’s encountering, or perhaps it wants to ask for advice about those events.
The UIApplication class implements the required behavior of an application. Instead of forcing you to subclass
UIApplication to receive simple notifications about the current state of the application, the UIApplication class delivers
those notifications by calling specific methods of its assigned delegate object. An object that implements the methods of the
UIApplicationDelegate protocol can receive those notifications and provide an appropriate response.
You specify in the interface block that your class conforms to, or adopts, a protocol by putting the name of the protocol in angle
brackets (<...>) after the name of the class from which it inherits. You indicated adoption of the UITextFieldDelegate
protocol in Your First iOS App in the following line of code:
@interface HelloWorldViewController : UIViewController <UITextFieldDelegate> {
You do not have to declare the protocol methods you implement.
The declaration of a protocol looks similar to that of a class interface, with the exceptions that protocols do not have a parent class and
they do not define instance variables (although they can declare properties). The following example shows a simple protocol
declaration with one method:
@protocol MyProtocol
- (void)myProtocolMethod;
@end
For many delegate protocols, adopting a protocol is simply a matter of implementing the methods defined by that protocol. There are
some protocols that require you to state explicitly that you support the protocol, and protocols can specify both required and optional
methods.
When you begin exploring the header files of the Objective-C frameworks, you’ll soon encounter a line similar to this one:
@interface NSDate (NSDateCreation)
This line declares a category through the syntactical convention of enclosing the name of the category in parentheses. A category is a
feature of the Objective-C language that enables you to extend the interface of a class without having to subclass it. The methods in
the category become part of the class type (within the scope of your program) and are inherited by all the class’s subclasses. You can
send a message to any instance of the class (or its subclasses) to invoke a method defined in the category.
You can use categories as a means for grouping related method declarations within a header file. You can even put different category
declarations in different header files. The frameworks use these techniques throughout their header files for clarity.
You can also use an anonymous category known as a class extension to declare private properties and private methods in the
implementation (.m) file. A class extension looks like a category except there is no text between the parentheses. For example, here is
a typical class extension:
@interface MyAppDelegate ()
@property (strong) MyDataObject *data;
@end
Defined Types and Coding Strategies
Objective-C has several terms that you should not use as the names of variables because they are reserved for special purposes. Some
of these terms are compiler directives that are prefixed with at-signs (@), for example, @interface and @end. Other reserved terms
are defined types and the literals that go with those types. Objective-C uses a number of defined types and literals that you won’t find
in ANSI C. In some cases, these types and literals replace their ANSI C counterparts. The following table describes a few of the
important ones, including the allowable literals for each type.
Type
id
Description and literal
The dynamic object type. The negative literal for both dynamically and statically typed objects is nil.
Class The dynamic class type. Its negative literal is Nil.
SEL
The data type (typedef) of a selector; this data type represents a method signature at runtime. Its negative literal is NULL.
BOOL
A Boolean type. The literal values are YES and NO.
You often use these defined types and literals in error-checking and control-flow code. In your program’s control-flow statements,
you can test the appropriate literal to determine how to proceed. For example:
NSDate *dateOfHire = [employee dateOfHire];
if (dateOfHire != nil) {
// handle this case
}
To paraphrase this code, if the object representing the date of hire is not nil—in other words, if it is a valid object—then the logic
proceeds in a certain direction. Here’s a shorthand way of doing the same branching:
NSDate *dateOfHire = [employee dateOfHire];
if (dateOfHire) {
// handle this case
}
You can even reduce these lines of code further (assuming you don’t need a reference to the dateOfHire object):
if ([employee dateOfHire]) {
// handle this case
}
You handle Boolean values in much the same way. In this example, the isEqual: method returns a Boolean value.
BOOL equal = [objectA isEqual:objectB];
if (equal == YES) {
// handle this case
}
You can shorten this code in the same way you can for the code that tests for the absence or presence of nil.
In Objective-C, you can send a message to nil with no ill effects. Indeed there is no effect at all, except that the runtime returns nil
if the method is supposed to return an object. Return values from messages sent to nil are guaranteed to work as long as what is
returned is typed as an object.
Two other important reserved terms in Objective-C are self and super. The first term, self, is a local variable that you can use
within a message implementation to refer to the current object; it is equivalent to this in C++. You can substitute the reserved word
super for self, but only as the receiver in a message expression. If you send a message to self, the runtime first looks for the
method implementation in the current object’s class; if it can’t find the method there, it looks for it in its superclass (and so on). If you
send a message to super, the runtime first looks for the method implementation in the superclass.
The primary uses of both self and super have to do with sending messages. You send a message to self when the method to
invoke is implemented by the class of self. For example:
[self doSomeWork];
self is also used in dot notation to invoke the accessor method synthesized by a declared property. For example:
NSString *theName = self.name;
You often send messages to super in overrides (that is, reimplementations) of methods inherited from a superclass. In this case, the
method invoked has the same signature as the method overridden.
Acquire Foundational Programming Skills
The Foundation framework, as its name suggests, is the foundational toolkit for all programming for both iOS and OS X. You need to
become familiar with this toolkit to be a successful developer for these platforms.
Foundation defines dozens of classes and protocols for a variety of purposes, but three categories of classes and protocols stand out as
particularly fundamental:
 The root class and related protocols. The root class, NSObject, along with a protocol of the same name, specifies the basic
interface and behavior of all Objective-C objects. There are also protocols a class can adopt so that clients can copy instances of
the class and encode their state.
 Value classes. A value class generates an instance (called a value object) that is an object-oriented wrapper for a primitive data
type such as a string, a number, a date, or binary data. Instances of the same value class with the same encapsulated value are
considered equal.
 Collection classes. An instance of a collection class (called a collection) manages a group of objects. What distinguishes a
particular type of collection is how it lets you access the objects it contains. Often the items in a collection are value objects.
Collections and value objects are extremely important in Objective-C programming because you frequently find them as the
parameters and return values of methods.
The Root Class and Objective-C Objects
In a class hierarchy, a root class inherits from no other class and all other classes in the hierarchy ultimately inherit from it.
NSObject is the root class of Objective-C class hierarchies. From NSObject, other classes inherit a basic interface to the
Objective-C runtime system. And from NSObject, the instances of these classes derive their fundamental nature as Objective-C
objects.
But by itself, an NSObject instance cannot do anything useful beyond being a simple object. To add any properties and logic
specific to your program, you must create one or more classes inheriting from NSObject or from any other class that directly or
indirectly inherits from NSObject.
NSObject adopts the NSObject protocol, which declares additional methods common to the interfaces of all objects. In addition,
NSObject.h (the header file containing the class definition of NSObject) includes declarations of the NSCopying,
NSMutableCopying, and NSCoding protocols. When a class adopts these protocols, it augments the basic object behaviors with
object-copying and object-encoding capabilities. Model classes—those classes whose instances encapsulate application data and
manage that data—frequently adopt the object-copying and object-encoding protocols.
The NSObject class and related protocols define methods for creating objects, for navigating the inheritance chain, for interrogating
objects about their characteristics and capabilities, for comparing objects, and for copying and encoding objects. Much of the
remainder of this article describes the basic requirements for most of these tasks.
Think in Terms of Objects
At runtime, an app is a network of cooperating objects; these objects communicate with each other to get the work of the app done.
Each object plays a role, has at least one responsibility, and is connected to at least one other object. (An object in isolation is of little
value.) As illustrated in the figure below, the objects in a network include both framework objects and application objects.
Application objects are instances of a custom subclass, usually of a framework superclass. An object network is commonly known as
an object graph.
You establish these connections, or relationships, between objects through references. There are many language forms of references,
among them instance variables, global variables, and even (within a limited scope) local variables. Relationships can be one-to-one or
one-to-many and can express notions of ownership or parent-child correspondence. They are a means for one object to access,
communicate with, or control other objects. A referenced object becomes a natural receiver of messages.
Messages between objects in an app are critical to the functional coherence of the app. Like a musician in an orchestra, each object in
an app has a role, a limited set of behaviors it contributes to the app. An object might display an oval surface that responds to taps, or
it might manage a collection of data-bearing objects, or it might coordinate the major events in the life of the app. But for its
contributions to be realized, it must be able to communicate them to other objects. It must be able to send messages to other objects in
the app or be able to receive messages from other objects.
With strongly coupled objects—objects connected through direct references—sending messages is an easy matter. But for objects that
are loosely coupled—that is, objects far apart in the object graph—an app has to look for some other communication approach. The
Cocoa Touch and Cocoa frameworks feature many mechanisms and techniques enabling communication between loosely coupled
objects (as illustrated in the figure below). These mechanisms and techniques, all based on design patterns (which you will learn more
about later), make it possible to efficiently construct robust and extensible apps.
Create Objects
You usually create an object by allocating it and then initializing it. Although these are two discrete steps, they are closely linked.
Many classes also let you create an object by calling a class factory method.
Create an Object by Allocating and Initializing It
To allocate an object, you send an alloc message to the object’s class and get back a “raw” (uninitialized) instance of the class.
When you allocate an object, the Objective-C runtime allocates enough memory for the object from application virtual memory. In
addition to allocating memory, the runtime does a few other things during allocation, such as setting all instance variables to zero.
Immediately after allocating the raw instance, you must initialize it. Initialization sets an object’s initial state—that is, its instance
variables and properties—to reasonable values and then returns the object. The purpose of initialization is to return a usable object.
In the frameworks, you will find many methods called initializers that initialize objects, but they all have similarities in their form.
Initializers are instance methods that begin with init and return an object of type id. The root class, NSObject, declares the init
method, which all other classes inherit. Other classes may declare their own initializers, each with its own keywords and parameter
types. For example, the NSURL class declares the following initializer:
- (id)initFileURLWithPath:(NSString *)path isDirectory:(BOOL)isDir
When you allocate and initialize an object, you nest the allocation call inside the initialization call. Using the above initializer as an
example:
NSURL *aURL = [[NSURL alloc] initFileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
As a safe programming practice, you can test the returned object to verify that the object was created. If something happens during
either stage that prevents the object’s creation, the initializer returns nil. Although Objective-C lets you send a message to nil
without negative consequences (for example, without thrown exceptions), your code might not work as expected because no method
is called. You should use the instance returned by the initializers instead of the one returned by the alloc method.
Create an Object by Calling a Class Factory Method
You can also create an object by calling a class factory method—a class method whose purpose is to allocate, initialize, and return an
instance of itself. Class factory methods are conveniences because they permit you to create an object in one step rather than two.
They are of the form:
 + (type)className... (where className excludes any prefix)
Some classes of an Objective-C framework define class factory methods that correspond to initializers of the class. For example,
NSString declares the following two methods:
- (id)initWithFormat:(NSString *)format, ...;
+ (id)stringWithFormat:(NSString *)format, ...;
Here is an example of how you might use this class factory of NSString:
NSString *myString = [NSString stringWithFormat:@"Customer: %@",
self.record.customerName];
Manage the Object Graph to Avoid Memory Leaks
The objects in an Objective-C program compose an object graph: a network of objects formed by each object’s relationships with—or
references to—other objects. The references an object has are either one-to-one or (via collection objects) one-to-many. The object
graph is important because it is a factor in the longevity of objects. The compiler examines the strength of references in an object
graph and adds retain and release messages where appropriate.
Note: Recent versions of the Objective-C runtime implement Automatic Reference Counting (ARC). ARC makes explicit memory
management—that is, retaining and releasing objects—unnecessary. You should always use ARC in new application projects, where
it is the default.
You form references between objects through basic C and Objective-C constructs such as global variables, instance variables, and
local variables. Each of these constructs carries with it an implied scope; for example, the scope of an object referenced by a local
variable is the functional block in which it is declared. Just as important, references between objects are either strong or weak. A
strong reference indicates ownership; the referring object owns the referenced object. A weak reference implies that the referring
object does not own the referenced object. The lifetime of an object is determined by how many strong references there are to it. An
object is not freed as long as there is a strong reference to it.
References in Objective-C are strong by default. Usually this is a good thing, enabling the compiler to manage the runtime life of
objects so that objects are not freed while you’re using them. However, if you’re not careful, strong references between objects can
form an unbroken chain of references, as illustrated on the left in the diagram below. With such an unbroken chain, it’s possible that
the runtime will free none of the objects because there is a strong reference to each of them. Consequently, a strong reference cycle
can cause your program to leak memory.
For the objects in the figure, if you break the reference between A and B, the subgraph consisting of B, C, D, and E lives on “forever”
because these objects are bound together by a cycle of strong references. By introducing a weak reference from E to B, you break this
strong reference cycle.
The fix for strong reference cycles is the judicious use of weak references. The runtime keeps track of both weak references and
strong references to an object. After there are no strong references to an object, it frees that object and sets any weak references to the
object to nil. For variables (global, instance, and local), use the __weak qualifier just before the variable name to mark the
reference as weak. For properties, use the weak option. You should use weak references for the following kinds of references:
 Delegates
 @property(weak) id delegate;
 You will learn about delegates and targets in the Design Patterns article “Streamline Your App with Design Patterns.”
 Outlets that are not references to top-level objects
 @property(weak) IBOutlet NSString *theName;
 An outlet is a connection (or reference) between objects that is archived in a storyboard or nib file and restored when an app
loads the storyboard or nib file. An outlet for a top-level object in a storyboard or nib file—typically a window, view, view
controller, or other controller—should be strong (the default, so unmarked).
 Targets
 (void)setTarget:(id __weak)target
 References to self in blocks
 __block typeof(self) tmpSelf = self;
 [self methodThatTakesABlock:^ {

[tmpSelf doSomething];
 }];
 A block forms a strong reference to variables it captures. If you use self within a block, the block forms a strong reference to
self, so if self also has a strong reference to the block (which it typically does), a strong reference cycle results. To avoid the
cycle, you need to create a weak (or __block) reference to self outside the block, as in the example above.
Manage Object Mutability
A mutable object is one whose state you can change after creating the object. You typically make changes through properties or
accessor methods. An immutable object is one whose encapsulated state you cannot change after creating the object. The instances
you’ll create of most classes of the Objective-C frameworks are mutable, yet a few are immutable. Immutable objects provide you
with the following benefits:
 An immutable object won’t unexpectedly change in value while you’re using it.
 For many types of objects, application performance is improved if the object is immutable.
In Objective-C frameworks, the instances of immutable classes usually are ones that encapsulate collections of discrete or buffered
values—for example, arrays and strings. These classes usually have mutable variants with “Mutable” in their names. For example,
there is the NSString class (immutable) and the NSMutableString class. Note that some immutable objects that encapsulate
discrete values, such as NSNumber or NSDate, do not have mutable class variants.
Use mutable objects instead of the immutable variant when you expect to change an object’s contents incrementally and frequently. If
you receive an object from a framework that is typed as an immutable object, respect that return type; don’t attempt to change the
object.
Create and Use Value Objects
A value object is an object that encapsulates a primitive value (of a C data type) and provides services related to that value. Value
objects represent scalar types in object form. The Foundation framework provides you with the following classes that generate value
objects for strings, binary data, dates and times, numbers, and other values:





NSString and NSMutableString
NSData and NSMutableData
NSDate
NSNumber
NSValue
Value objects are important in Objective-C programming. You frequently encounter these objects as the parameters and return values
of methods and functions that your application calls. By passing value objects, different parts of a framework or even different
frameworks can exchange data. Because value objects represent scalar values, you can use them in collections and wherever else
objects are required. But beyond their commonness and consequent necessity, value objects have an advantage over the primitive
types they encapsulate: They enable you to perform certain operations on the encapsulated value in a simple yet efficient manner. The
NSString class, for example, has methods for searching for and replacing substrings, for writing strings to files or (preferably)
URLs, and for constructing file-system paths.
Sometimes you’ll find it more efficient and straightforward to use primitive types—that is, values typed as int (integer), float, and
so on. A primary example of such a situation is computing a value. Consequently, NSNumber and NSValue objects are less
commonly used as parameters and return values in framework methods. However, many of the frameworks declare their own numeric
data types and use these types for parameters and return values; examples are NSInteger and CGFloat. You should use these
framework-defined types where appropriate because they help you to abstract your code away from the underlying platform.
The Basics of Using Value Objects
The basic pattern for creating a value object is for your code or framework code to create it from data of the primitive type (and then
perhaps pass it in a method parameter). In your code, you later access the encapsulated data from the object. The NSNumber class
provides the clearest example of this approach:
int n = 5; // Value assigned to primitive type
NSNumber *numberObject = [NSNumber numberWithInt:n]; // Value object created from
primitive type
int y = [numberObject intValue]; // Encapsulated value obtained from value object (y ==
n)
Most “value” classes declare both initializers and class factory methods for creating their instances. Some classes—NSString and
NSData, in particular—also provide initializers and class factory methods for creating their instances from primitive data stored in
local or remote files as well as from data in memory. These classes also provide complementary methods for writing strings and
binary data to files or to URL-specified locations. The code in the following example calls the initWithContentsOfURL:
method to create an NSData object from the contents of a file located by a URL object; after using the data, the code writes the data
object back to the file system:
NSURL *theURL = // Code that creates a file URL from a string path...
NSData *theData = [[NSData alloc] initWithContentsOfURL:theURL];
// use theData...
[theData writeToURL:theURL atomically:YES];
In addition to creating value objects and letting you access their encapsulated values, most value classes provide methods for simple
operations such as object comparison.
When you declare instances of the value classes as properties, you should use the copy option.
Strings and the NSString Literal
As a superset of C, Objective-C supports the same conventions for specifying strings as does C: Single characters are enclosed by
single quotes and strings of characters are surrounded by double quotes. But Objective-C frameworks typically do not use C strings.
Instead, they use NSString objects.
You created a formatted string when you created the HelloWorld app in Your First iOS App:
NSString *greeting = [[NSString alloc] initWithFormat:@"Hello, %@!", nameString];
The NSString class provides an object wrapper for strings, thereby offering such advantages as built-in memory management for
storing arbitrary-length strings, support for different character encodings (particularly Unicode), and printf-style formatting
utilities. Because you commonly use such strings, Objective-C provides a shorthand notation for creating NSString objects from
constant values. To use this NSString literal, just precede a normal, double-quoted string with the at sign (@), as shown in the
following examples:
// Create the string "My String" plus carriage return.
NSString *myString = @"My String\n";
// Create the formatted string "1 String".
NSString *anotherString = [NSString stringWithFormat:@"%d %@", 1, @"String"];
// Create an Objective-C string from a C string.
NSString *fromCString = [NSString stringWithCString:"A C string"
encoding:NSASCIIStringEncoding];
NSNumber Literals
Objective-C also offers a shorthand notation for creating NSNumber objects, removing the need to call initializers or class factory
methods to create such objects. Simply precede the numeric value with the at sign (@) and optionally follow it with a value-type
indicator. For example, to create NSNumber objects encapsulating an integer value and a double value, you could write the
following:
NSNumber *myIntValue
= @32;
NSNumber *myDoubleValue = @3.22346432;
You can even use NSNumber literals to create encapsulated Boolean and character values.
NSNumber *myBoolValue = @YES;
NSNumber *myCharValue = @'V';
You can create NSNumber objects representing unsigned integers, long integers, long long integers, and float values by appending
the letters “U”, “L”, “LL”, and “F”, respectively, to the notated value. For example, to create an NSNumber encapsulating a float
value, you could write the following:
NSNumber *myFloatValue = @3.2F
Dates and Times
An NSDate object is different from other kinds of value objects because of the distinctive nature of time as a primitive value. A date
object encapsulates the interval, in seconds, from a reference date. That reference date is the first instant of January 1, 2001 GMT.
You can do little with an instance of NSDate just by itself. It does represent a moment in time, but that representation is without the
context provided by a calendar, a time zone, and the temporal conventions of a locale. Fortunately, there are Foundation classes
representing these conceptual entities:
 NSCalendar and NSDateComponents—You can associate the date with a calendar and then derive temporal units from the
calendar for the date such as year, month, hour, and day of week. You can also perform calendrical calculations.
 NSTimeZone—When a date and time must reflect the time zone of an area, you can associate a time-zone object with a
calendar.
 NSLocale—A locale object encapsulates cultural and linguistic conventions, including those related to time.
The following code snippet illustrates how you can use an NSDate object with these other objects to obtain the information you want
(in this case, the current time printed as hours, minutes, and seconds).
NSDate *now = [NSDate date]; // 1
NSCalendar *calendar = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar]; // 2
[calendar setTimeZone:[NSTimeZone systemTimeZone]]; // 3
NSDateComponents *dc = [calendar components:(NSHourCalendarUnit|NSMinuteCalendarUnit|
NSSecondCalendarUnit) fromDate:now]; // 4
NSLog(@"The time is %d:%d:%d", [dc hour], [dc minute], [dc second]); // 5
This list explains each numbered line of code:
1.
2.
3.
4.
5.
Creates a date object representing the current instant
Creates an object representing the Gregorian calendar
Sets the calendar object with an object representing the time zone specified in System Preferences.
Calls the components:fromDate: method on the calendar object, passing in the date object created in step 1. This call
returns an object containing the hour, minute, and second components of the date object.
Logs the current hour, minute, and second to the console
Although this example logs the result, the preferred approach for displaying date information in an app’s user interface is to use date
formatters (instances of the NSDateFormatter class). You should always use the appropriate class and method for calendrical
calculations; don’t hard-code numerical values for units such as minutes, hours, and days.
Create and Use Collections
A collection is an object that stores other objects in a certain way and allows clients to access those objects. You often pass collections
as parameters of methods and functions, and you often obtain collections as return values of methods and functions. Collections
frequently contain value objects, but they can contain any type of object. Most collections have strong references to the objects they
contain.
The Foundation framework has several types of collections, but three of them are particularly important in Cocoa Touch and Cocoa
programming: arrays, dictionaries, and sets. The classes for these collections come in immutable and mutable variants. Mutable
collections permit you to add and remove objects, but immutable collections can contain only the objects they were created with. All
collections allow you to enumerate their contents—in other words, to examine each of the contained objects in turn.
Different types of collections organize their contained objects in distinctive ways:
 NSArray and NSMutableArray — An array is an ordered collection of objects. You access an object by specifying its
position (that is, its index) in the array. The first element in an array is at index 0 (zero).
 NSDictionary and NSMutableDictionary — A dictionary stores its entries as key-value pairs; the key is a unique
identifier, usually a string, and the value is the object you want to store. You access this object by specifying the key.
 NSSet and NSMutableSet — A set stores an unordered collection of objects, with each object occurring only once. You
generally access objects in the set by applying tests or filters to objects in the set.
Because of their storage, access, and performance characteristics, one type of collection can be better suited to a particular task than
another one.
You can create arrays and dictionaries and access the values they contain either by calling methods of NSArray and
NSDictionary or by using special Objective-C container literals and subscripting techniques. The following sections describe both
approaches.
Store Objects in a Certain Order in Arrays
Arrays store objects in an ordered sequence. Thus, you use arrays when the order of objects in the collection is important. For
example, many applications use arrays to give content to the rows of a table view or the items in a menu; the object at index 0
corresponds to the first row, the object at index 1 corresponds to the second row, and so on. Access times for objects in arrays are
slower than they are for objects in a set.
Creating Arrays
The NSArray class gives you many initializers and class factory methods for creating and initializing arrays, but a few methods are
particularly common and useful. You can create an array from a series of objects with the arrayWithObjects:count: and
arrayWithObjects: methods (and their corresponding initializers). With the former method, the second parameter specifies the
number of objects in the first parameter; with the latter method, you terminate the comma-separated series of objects with nil.
// Compose a static array of string objects
NSString *objs[3] = {@"One", @"Two", @"Three"};
// Create an array object with the static array
NSArray *arrayOne = [NSArray arrayWithObjects:&(*objs) count:3];
// Create an array with a nil-terminated list of objects
NSArray *arrayTwo = [[NSArray alloc] initWithObjects:@"One", @"Two", @"Three", nil];
When creating mutable arrays, you can use the arrayWithCapacity: (or initWithCapacity:) method to create the array.
The capacity parameter gives a hint to the class about the expected size of the array, thus making the array more efficient at runtime.
The array can even exceed the specified capacity.
You can also create arrays using the container literal @[ . . . ], where the items between the brackets are comma-separated objects.
For example, to create an array containing a string, a number, and a date, you could write the following:
NSArray *myArray = @[ @"Hello World", @67, [NSDate date] ];
Accessing Objects in Array
Generally, you call the objectAtIndex: method to access an object in an array by specifying its index position (zero-based) in the
array:
NSString *theString = [arrayTwo objectAtIndex:1]; // returns second object in array
NSArray gives you other methods to access either the objects in an array or their indexes. For example, there is lastObject,
firstObjectCommonWithArray:, and indexOfObjectPassingTest:.
Instead of using a method of NSArray to access an object in an array, you can use subscripting notation. For example, to access the
second object in myArray (created above), you might write something like this:
id theObject = myArray[1];
Another common task with arrays is to do something with each of the objects in the array—this is a procedure known as enumeration.
You often enumerate arrays to determine whether an object or objects match a certain value or condition and, if one does, complete an
action with it. You can take one of three approaches for enumerating arrays: fast enumeration, enumeration with a block, or use of an
NSEnumerator object. Fast enumeration, as its name implies, is typically faster than using other techniques to access the objects in
an array. Fast enumeration is a language feature that requires a specific syntax:
for (type variable in array){ /* inspect variable, do something with it */ }
For example:
NSArray *myArray = // get array
for (NSString *cityName in myArray) {
if ([cityName isEqualToString:@"Cupertino"]) {
NSLog(@"We're near the mothership!");
break;
}
}
Several NSArray methods enumerate arrays with blocks, the simplest of them being enumerateObjectsUsingBlock:. The
block has three parameters: the current object, its index, and a by-reference Boolean value, which if set to YES terminates the
enumeration. The code in the block performs exactly the same work as the code between the braces in a fast-enumeration statement.
NSArray *myArray = // get array
[myArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isEqual:@"Cupertino"]) {
NSLog(@"We're near the mothership!");
*stop = YES;
}
}];
Managing Mutable Arrays
NSArray has other methods that sort arrays, search arrays, and invoke a method on each object in an array.
You can add an object to a mutable array by calling the addObject: method; the object is placed at the end of the array. You can
also use insertObject:atIndex: to put an object at a particular location in a mutable array. You can remove an object from a
mutable array by calling the removeObject: method or the removeObjectAtIndex: method.
You can also use subscripting notation to insert an object at a specific location in a mutable array.
NSMutableArray *myMutableArray = [NSMutableArray arrayWithCapacity:1];
NSDate *today = [NSDate date];
myMutableArray[0] = today;
Store Key-Value Pairs in Dictionaries
You use a dictionary to store objects as key-value pairs—that is, an identifier (a key) paired with an object (a value). Dictionaries are
unordered collections because the key-value pairs can be in any order. Although a key can be virtually anything, it is typically a string
that describes the value—for example, NSFileModificationDate or UIApplicationStatusBarFrameUserInfoKey
(which are string constants). When there are public keys, dictionaries are a great way to pass information of any kind between objects.
Creating Dictionaries
Through its initializers and class factory methods, the NSDictionary class gives you many ways to create dictionaries, but two
class methods are particularly common: dictionaryWithObjects:forKeys: and dictionaryWithObjectsAndKeys:
(or their corresponding initializers). With the former method, you pass in an array of objects and an array of keys; the keys are
positionally matched with their values. With the second method, you specify the first object value and then its key, the second object
value and then its key, and so on; you signal the end of this series of objects with nil.
// First create an array of keys and a complementary array of values
NSArray *keyArray = [NSArray arrayWithObjects:@"IssueDate", @"IssueName", @"IssueIcon",
nil];
NSArray *valueArray = [NSArray arrayWithObjects:[NSDate date], @"Numerology Today",
self.currentIssueIcon, nil];
// Create a dictionary, passing in the key array and value array
NSDictionary *dictionaryOne = [NSDictionary dictionaryWithObjects:valueArray
forKeys:keyArray];
// Create a dictionary by alternating value and key and terminating with nil
NSDictionary *dictionaryTwo = [[NSDictionary alloc] initWithObjectsAndKeys:[NSDate date],
@"IssueDate", @"Numerology Today", @"IssueName", self.currentIssueIcon, @"IssueIcon",
nil];
As with arrays, you can create an NSDictionary object by using the container literal @{key : value, …} where “…” indicates
any number of key-value pairs. For example, the following code creates an immutable dictionary object with three key-value pairs:
NSDictionary *myDictionary = @{
@"name" : NSUserName(),
@"date" : [NSDate date],
@"processInfo" : [NSProcessInfo processInfo]
};
Accessing Objects in Dictionaries
You access an object value in a dictionary by calling the objectForKey: method, specifying a key as a parameter.
NSDate *date = [dictionaryTwo objectForKey:@"IssueDate"];
You can also access an object in a dictionary using subscripting. The key appears between brackets right after the dictionary variable.
NSString *theName = myDictionary[@"name"];
Managing Mutable Dictionaries
You can insert and delete items in mutable dictionaries by calling the setObject:forKey: and removeObjectForKey:
methods. The setObject:forKey: method replaces any existing value for the given key. These methods are fast.
You can also use subscripting to add a key-value pair to a mutable dictionary. The key is subscripted on the left side of the
assignment, and the value is on the right side.
NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc] init];
mutableDict[@"name"] = @"John Doe";
Store Unordered Objects in Sets
Sets are collection objects similar to arrays except that the items they contain are unordered instead of ordered. Rather than access
objects in the set by index location or through a key, you access them randomly (using the anyObject method), by enumerating the
collection, or by applying a filter or test to the set.
Although set objects are not as common in Objective-C programming as dictionaries and arrays, they are an important collection type
in certain technologies. In Core Data (a data-management technology), when you declare a property for a to-many relationship, the
property type should be NSSet or NSOrderedSet. Sets are also important in native touch-event handling in the UIKit framework,
for example:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *theTouch = [touches anyObject];
// handle the touch...
}
Ordered sets are an exception to the basic definition of a set. In an ordered set, the order of the items in the set is important. Testing
for membership in an ordered set is faster than it is in an array.
Verify Object Capabilities at Runtime
Introspection, a powerful and useful feature of Objective-C and the NSObject class, enables you to learn certain things about
objects at runtime. You can thus avoid mistakes in your code such, as sending a message to an object that doesn’t recognize it or
assuming that an object inherits from a given class when it doesn’t.
There are three important types of information that an object can divulge about itself at runtime:
 Whether it’s an instance of a particular class or subclass
 Whether it responds to a message
 Whether it conforms to a protocol
Discover Whether an Object Is an Instance of a Particular Class or its Subclasses
To discover whether an object is an instance of a class or its subclasses, call the isKindOfClass: method on the object. An app
sometimes makes this check when it wants to discover the messages (implemented or inherited) that an app responds to.
static int sum = 0;
for (id item in myArray) {
if ([item isKindOfClass:[NSNumber class]]) {
int i = (int)[item intValue];
sum += i;
}
}
The isKindOfClass: method takes an object of type Class as a parameter; to get this object, you call the class method on the
class symbol. Then evaluate the Boolean value returned by this method and proceed accordingly.
NSObject declares other methods for discovering information about object inheritance. The isMemberOfClass: method, for
example, tells you whether an object is an instance of a specific class, whereas isKindOfClass: tells you whether the object is a
member of that class or any of its descendent classes.
Discover Whether an Object Responds to a Message
To discover whether an object responds to a message, call the respondsToSelector: method on the object. App code often
verifies that an object responds to a message before it sends the message to the object.
if ([item respondsToSelector:@selector(setState:)]) {
[item setState:[self.arcView.font isBold] ? NSOnState : NSOffState];
}
The respondsToSelector: method takes a selector as its parameter. A selector is an Objective-C data type for runtime
identifiers of methods; you specify a selector using the @selector compiler directive. In your code, evaluate the Boolean value
returned by this method and proceed accordingly.
For identifying the messages an object responds to, calling respondsToSelector: is generally more useful than evaluating class
type. For example, a more recent version of a class might implement a method that isn’t found in a prior version.
Discover Whether an Object Conforms to a Protocol
To discover whether an object conforms to a protocol, call the conformsToProtocol: method on the object.
- (void) setDelegate:(id __weak) obj {
NSParameterAssert([obj conformsToProtocol:
@protocol(SubviewTableViewControllerDataSourceProtocol)]);
delegate = obj;
}
The conformsToProtocol: method takes a runtime identifier of a protocol as a parameter; you specify this identifier using the
@protocol compiler directive. Evaluate the Boolean value returned by this method and proceed accordingly. Note than an object
can conform to a protocol without implementing its optional methods.
Compare Objects
You can compare two objects by using the isEqual: method. The object receiving the message is compared to the passed-in object;
if they’re the same, the method returns YES. For example:
BOOL objectsAreEqual = [obj1 isEqual:obj2];
if (objectsAreEqual) {
// do something...
}
Note that object equality is different from object identity. For the latter, use the equality operator == to test whether two variables
point to the same instance.
What is compared when you compare two objects of the same class? That depends on the class. The root class, NSObject, uses
pointer equality as the basis of comparison. Subclasses at any level can override their superclass’s implementation to base the
comparison on class-specific criteria, such as object state. For example, a hypothetical Person object might equal another Person
object if the first-name, last-name, and birth-date attributes of both objects match.
The value and collection classes of the Foundation framework declare comparison methods of the form isEqualToType:, where
Type is the class type minus the NS prefix—for example, isEqualToString: and isEqualToDictionary:. The comparison
methods assume that the passed-in object is of the given type and raise an exception if it is not.
Copy Objects
You make a copy of an object by sending a copy message to it.
NSArray *myArray = [yourArray copy];
To be copied, the class of the receiving object must conform to the NSCopying protocol. If you want your objects to be copyable,
you must adopt and implement the copy method of this protocol.
You sometimes copy an object obtained from elsewhere in a program when you want to ensure the object’s state does not change
while you’re using it.
Copying behavior is specific to a class and depends upon the specific nature of the instance. Most classes implement deep copying,
which makes a duplicate of all instance variables and properties; some classes (for example, the collection classes) implement shallow
copying, which only duplicates the references to those instance variables and properties.
Classes that have mutable and immutable variants also declare a mutableCopy method to create a mutable copy of an object. For
example, if you call mutableCopy on an NSString object, you get an instance of NSMutableString.
Download