• Aucun résultat trouvé

Delegation and Core Location

Dans le document Chapter 1. A Simple iPhone Application (Page 85-89)

Managing Memory in RandomPossessions

Chapter 4. Delegation and Core Location

In this chapter we introduce delegation, a recurring design pattern of Cocoa Touch development, and demonstrate its use with the Core Location service, which provides the location-finding features of the iPhone.

Delegation

We spend a lot of time sending messages to objects. Sometimes, however, we want objects to send messages to us – a callback. A callback is a function that is triggered when an event occurs. Usually, this is an event that happens in response to user input. We don’t exactly know when this event might occur, but we set up a callback so that when it does occur, our code will be called. In some systems, callbacks are sent to objects that are known as listeners.

In Cocoa Touch, callbacks are implemented using a technique known as delegation. Let’s start with an example. Every instance of UITextView has a delegate property, which is a pointer to an object. That object is “the delegate” of the text view. You can set that pointer to refer to any object, as long as that object conforms to the protocol of the class for which it is a delegate. For instance, when you create a class that will be a UITextView delegate, you need to declare it to conform to the UITextViewDelegate protocol. You declare which protocols a class conforms to by listing the names of the protocols in a comma-delimited list in angled brackets after the name of the superclass:

// SuperGoodController conforms to the UITextViewDelegate // and SomeOtherDelegate protocol.

@interface SuperGoodController : NSObject <UITextViewDelegate, SomeOtherDelegate>

A protocol is simply a list of method declarations. (Other languages, like Java, sometimes call them interfaces.) When a class conforms to a protocol, it is

promising to implement all required methods from that protocol and reserving the option to implement any optional methods. For example, here is the protocol that declares all the delegate methods for UITextView:

@protocol UITextViewDelegate

@optional

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView;

- (BOOL)textViewShouldEndEditing:(UITextView *)textView;

- (void)textViewDidBeginEditing:(UITextView *)textView;

- (void)textViewDidEndEditing:(UITextView *)textView;

- (BOOL)textView:(UITextView *)textView

shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;

- (void)textViewDidChange:(UITextView *)textView;

- (void)textViewDidChangeSelection:(UITextView *)textView;

@end

Notice that this particular protocol doesn’t have any required methods (which is not unusual). Also notice that the first argument to all of the delegate methods is a pointer to the object that is sending the callback. This lets the delegate know exactly which object is sending it a delegate message and is always the case with delegate methods.

In Apple’s developer documentation, each protocol has its own page that lists and describes each method. To get to the documentation, go to the Help menu and click Developer Documentation. There you can search for the protocol.

By convention, the name of a delegate protocol is the name of the class doing the delegation suffixed with Delegate. For example, to find all of the delegate methods for a UITextView, search for UITextViewDelegate. The

“UITextViewDelegate Protocol Reference” is shown in Figure 4.1.

Figure 4.1. UITextViewDelegate Documentation

Once you have declared a class as conforming to a protocol, you find the methods you need in the documentation, implement them for that class, and you’re good to go. For example, if the delegate of a UITextView has implemented the method textViewDidChange:, that method will be called every time the user changes the text of that text view as shown in Figure 4.2.

Figure 4.2. A UITextView delegate

When implementing a delegate method, it is important to make sure you match the name and the types of arguments exactly as they are declared in the protocol.

If you change the name in any way (capitalization or spelling errors are the most common “changes”), the method will not get called. If you change the types of the arguments, your application may not work as you intend it to.

There are two basic categories of delegate methods. Some are “for-your-information” methods. These methods are sent to a delegate to inform

it that something has happened. For example, you would implement

textViewDidChange: to be informed when the text in a UITextView changes.

Other delegate methods are “what-should-I-do?” methods. These methods expect a response back from the delegate that will dictate the behavior of the delegating object. For example, if a delegate implements textView:shouldChangeTextInRa nge:replacementText:, it can prevent an inappropriate edit by returning NO.

Sometimes protocols have required methods. A class that conforms to a protocol that has required methods must implement those methods or else the compiler will warn you and your application will probably crash. How can you tell if a method is required? In the protocol reference, the absence of the text optional method next to the method name indicates that it is a required method. (Some versions of the documentation label the required methods instead of optional methods.)

You can also determine which methods are required by looking at the header file in which the protocol is declared. Any required methods appear above the @ optional directive in the protocol body. Methods that appear below the @optional directive are optional and do not have to be implemented by a class that conforms to that protocol. (If there is no @optional tag, then all methods in that protocol are required.)

// SuperCoolProtocol is a protocol that also // includes methods from the NSObject protocol

@protocol SuperCoolProtocol <NSObject>

Many classes use delegates: AVAudioPlayer, CLLocationManager,

NSNetServices, NSStream, NSURLConnection, NSXMLParser, CALayer, UIAccelerometer, UIApplication, UIPickerView, UIImagePickerController, UIScrollView, UITableView,UITextField, UIWebView, and UIWindow. Take a moment to browse through some of these protocol references. (Here’s a shortcut:

in Xcode, hold down the Option and Command keys and double-click the name of the protocol. The documentation browser will appear displaying a list of every method for that protocol.)

To review, in order implement delegate methods for an object, you must:

1. declare a class to conform to the object’s delegate protocol


2. implement the necessary delegate methods (required ones and optional ones you want to use) in the class


3. set the delegate pointer of the object to point to an instance of your class


Dans le document Chapter 1. A Simple iPhone Application (Page 85-89)

Documents relatifs